Fetch data between morning and evening - mysql

im trying to fetch the data between two times, i.e., morning (7:30AM to 7:30PM) evening (7:30PM to 7:30AM).
required only hour based output.{ > 7:30 < 19:30 as morning and > 19:30 < 7:30 as night)
Please suggest the query
Tablename: data
----------------
created_date services_name id
28-08-2022 18:54 KANE 1
28-08-2022 19:00 BAPLO 2
28-08-2022 23:22 BAPLO 3
28-08-2022 23:40 VLOTLS 4
29-08-2022 00:02 DELLP 5
29-08-2022 00:42 SECON 6
29-08-2022 02:00 BAPLO 7
29-08-2022 03:00 PRODC 8
29-08-2022 05:14 DELLP 9
29-08-2022 05:30 SECON 10
29-08-2022 05:42 SECON 11
im using below command to fetch output
SELECT
CONCAT( HOUR(created_date), ' to ', CONCAT( HOUR(created_date), ':59:59' ) ) as time_frame,
COUNT(*)
FROM
data
GROUP BY
DATE(created_date),
HOUR(created_date)
ORDER BY
DATE(created_date),
HOUR(created_date)
Out as below
0 to 0:59:59 2
2 to 2:59:59 1
3 to 3:59:59 1
5 to 5:59:59 3
18 to 18:59:59 1
19 to 19:59:59 1
23 to 23:59:59 2
But i required as
morning ( between 07:30 to 19:30) count is 2
evening ( between 19:30 to 07:30) count is 9

You can perform a UNION to get two separate counts, one for morning times and one evening times. Within the WHERE clause, you can convert created_date to a time format using the TIME() data type and then plug in your morning and evening times within the BETWEEN condition.
Note that you have to use the NOT operator to negate the BETWEEN operator for the evening count because BETWEEN works within a range (small to large 0..1, not large to small 1..0) so the NOT operator will essentially get everything else outside of the morning BETWEEN range.
SELECT 'Morning' as time_frame, COUNT(*) AS `count` FROM temp
WHERE TIME(created_date)
BETWEEN '07:30:00' AND '19:30:00'
UNION
SELECT 'Evening' as time_frame, COUNT(*) AS `count` FROM temp
WHERE TIME(created_date)
NOT BETWEEN '07:30:00' AND '19:30:00'
Output:
time_frame
count
Morning
2
Evening
9
See Fiddle.

Related

get the scheduling data based on 3 years in mysql

I have one table bibles that having two columns only i.e. is below:-
id chapter_name
1 Mathews 1
2 Mathews 2
3 Mathews 3
4 Mathews 4
... ....
... ....
364 Revelation 22 //Total Records only 364 fixed. that will not increase
Bible Scheduling starts from 5 sept 2021 for 3 years and ends on 31 Aug 2024 i.e basically bible repeats three time in 3 years.
Now Suppose today date is 8 Sept 2021
id chapter_name date_1 date_2 date_3
1 Mathews 1 2021-09-05 2022-09-04 2023-09-03
2 Mathews 2 2021-09-06 2022-09-05 2023-09-04
3 Mathews 3 2021-09-07 2022-09-06 2023-09-05
4 Mathews 4 2021-09-08 2022-09-07 2023-09-06
... ....
... ....
So now requested date is 8 spet 2021 i want to fetch the 4th record Mathews 4 and now suppose today date is 6 sept 2022 and now want to fetch the 3 row Mathews 3.
Note : these date columns are not stored in database. i have only two columns id, chapter_name.. Reason for not storing the dates because after three years i need to update again that dates to make scheduling works. Is there any way to fetch the rows?
Below answer works fine but I have two types of Bibles that starts from Id 1 to 364 another starts from 365 to 1456... 1st case
1 to 364 works.. but 365 to 1456 not works
If I understand correctly, then logic you want is:
where dateadiff(?, '2021-09-05') % 364 = id - 1
The ? is a parameter for the date you pass in.
You can start with some anchor date in the past, 2020-09-06 will do.
The id in your table is a number of days between the anchor date and the current date mod 364 (the number of rows in your table).
SELECT
id, chapter_name
FROM bibles
WHERE
id = DATEDIFF(CURRENT_DATE(), '2020-09-06') % 364 + 1
;
The DATEDIFF(CURRENT_DATE(), '2020-09-06') function returns the number of days between the current date and the anchor date 2020-09-06, i.e. the number of days between the date when the schedule started and now. This number can grow larger than 364 (the number of rows in your table). To "wrap" this number back to 0 when it is larger than 364 we use the modulo division (mod) or % operator. And then add 1, because ids in your table start with 1 (if they started with 0 you didn't have to add 1).
Try to run this query replacing the CURRENT_DATE() with your sample dates 2021-09-08 and 2022-09-06.
SELECT DATEDIFF('2021-09-08', '2020-09-06') % 364 + 1;
returns 4 (4th row)
SELECT DATEDIFF('2022-09-06', '2020-09-06') % 364 + 1;
returns 3 (3rd row)
It means that if you run the full query with the CURRENT_DATE() function on 2021-09-08 it will return a row with id=4. When you run the query on 2022-09-06 it will return a row with id=3.

MySql - count records since last time it was X o'clock

I need to count records created since it was last 9:00am.
so at 8:59am I need to count all records since yesterday at 9:00am and at 9:01am I will need to count since today at 9:00am,
data sample
ID | created
----------------------------------
1 | 2018-11-13 17:00
2 | 2018-11-13 09:00
3 | 2018-11-13 08:01
4 | 2018-11-12 13:00
5 | 2018-11-11 17:31
running the query at 13-11-2018 8:59am should return 2 (rows 3,4)
running the query at 13-11-2018 9:01am should return 1 (rows 2)
the query I'm looking for should be something like:
SELECT count(id) FROM myTable WHERE created > "TIME_SINCE_9AM()"
any help?
I figured out a solution, I hoped for a prettier query but it works...
I'm using IF statement to determine if right now is before 9am or after and running count on records accordingly, (the H var is for testing purposes, if you put 18 in there it works since last 18:00)
SET #H = "9";
SELECT
IF (TIMEDIFF(NOW(), SUBDATE(CURDATE(),INTERVAL (-#H) HOUR))<0,
SUM(CASE WHEN created>SUBDATE(CURDATE(),INTERVAL (-#H+24) HOUR) THEN 1 ELSE 0 END),
SUM(CASE WHEN created>SUBDATE(CURDATE(),INTERVAL (-#H) HOUR) THEN 1 ELSE 0 END)
) counter
FROM mytable

Converting the result of a MySQL table as per requirement

The mysql table we work on has data in the following format:
entityId status updated_date
-------------------------------
1 1 29/05/2017 12:00
1 2 29/05/2017 03:00
1 3 29/05/2017 07:00
1 4 29/05/2017 14:00
1 5 30/05/2017 02:00
1 6 30/05/2017 08:00
2 1 31/05/2017 03:00
2 2 31/05/2017 05:00
.
.
So every entity id has 6 statuses, and every status has an update datetime. Each status has an activity attached to it.
For example 1 - Started journey
2 - Reached first destination
3 - Left Point A, moving towards B. etc
I need to get an output in the below format for specific entity id eg 3 and 4. I need the time for status 3 and 4 independently.
entity_id time_started_journey time_reached_first_destination
(update time of status 3) (update time of status 4)
--------------------------------------------------------------
1 29/05/2017 7:00 29/05/2017 14:00
2 30/05/2017 7:00 30/05/2017 16:00
Later I need to calculate the total time which would be the difference of the two.
How can I achieve the desired result using mysql.
I tried using Union operator but cannot do it separate columns.
Also, tried using case when operator with the below query but failed.
select distinct entityid,
(case status when 3 then freight_update_time else 0 end)
as starttime,
(case status when 4 then freight_update_time else 0 end) as endtime
from table ;
Can anyone throw light on this?
Conditional aggregation is one way to return a resultset that looks like that.
SELECT t.entityid
, MAX(IF(t.status=3,t.updated_date,NULL)) AS time_started_journey
, MAX(IF(t.status-4,t.updated_date,NULL)) AS time_reached_first_destination
FROM mytable t
WHERE t.status IN (3,4)
GROUP BY t.entityid
ORDER BY t.entityid
This is just one suggestion; the specification is unclear about what the query should do with duplicated status values for a given entityid.
There are other query patterns that will return similar results.
My query in MySQL
SELECT
e3.updated_date AS sta3,
e4.updated_date AS sta4
FROM
`prueba` AS e3
LEFT JOIN prueba AS e4
ON
e3.entityId = e4.entityId AND e4.status = 4
WHERE
e3.status = 3
OUTPUT:

Does any way to get the last inserted values in each days

id date calls
5 2015-02-17 01:06:01 1
6 2015-02-17 11:07:01 2
7 2015-02-17 23:06:01 3
8 2015-02-18 03:07:01 1
9 2015-02-18 09:06:01 2
10 2015-02-18 17:07:01 3
11 2015-02-18 22:06:01 4
12 2015-02-19 01:07:01 1
13 2015-02-19 08:06:01 2
14 2015-02-19 18:07:01 3
15 2015-02-19 23:06:01 4
my table structure is like this and I need to calculate the sum of call in each days. In this table, you can see that, the last call in feb 17 was at 23:06:01 and call count was 3. In feb 18 was at 22:06:01 and call count was 4. Can I get the sum of all this last call counts of each day.
You can use a subquery to determine which rows to sum (the ones matching the last call for each date, using MySQL it would be:
select sum(calls) sum_last_calls
from your_table
where `date` in (
select max(date) max_date
from your_table
group by date(`date`)
)
This query will return 11 as the sum (from 3+4+4).
The date() function used in the subquery is specific to your database and might need to be changed according to your specific database syntax - the point is that it should return the date without time (it could be date::date (Postgresql) or cast(date as date) (MSSQL and others)).
Sample SQL Fiddle for MySQL and Postgresql
Postgresql version:
select sum(calls) as calls
from (
select max(calls) as calls
from t
where date::date between '2015-02-17' and '2015-02-19'
group by date::date
) s

MySQL: a timespan available within consecutive times

I have a table with consecutive times and dates for an agenda.
ID date begin_time end_time
1 05-02-15 19:00:00 19:05:00
2 05-02-15 19:05:00 19:10:00
3 05-02-15 19:10:00 19:15:00
4 05-02-15 19:15:00 19:20:00
5 05-02-15 19:20:00 19:25:00
6 05-02-15 19:25:00 19:30:00
7 05-02-15 19:30:00 19:35:00
8 05-02-15 19:35:00 19:40:00
9 06-02-15 19:00:00 19:05:00
10 06-02-15 19:05:00 19:10:00
11 06-02-15 19:10:00 19:15:00
12
13
14 06-02-15 19:25:00 19:30:00
15 06-02-15 19:30:00 19:35:00
16 06-02-15 19:35:00 19:40:00
http://sqlfiddle.com/#!2/54d9f6
As you can see on 05-02-15 the time from 19:00 until 19:40 is consecutive
As you can see on 06-02-15 the time from 19:00 until 19:15 is consecutive
As you can see on 06-02-15 the time from 19:25 until 19:40 is consecutive
The begin time and end time always have a 5 minute difference.
I want to have all the dates, that have a consecutive timespan of x minutes. So when x = 30, the result is:
05-02-15
when x = 10, the result is:
05-02-15
06-02-15
Idea for an approach
Maybe the first step is to get all the consecutive parts, secondly count the number of records in a part (when x = 30, we need at least 30 min. / 5 min. = 6).
This query check if you have #x/5 free slots in next #x minutes. And if so, than them cover whole #x minutes interval, means them are consecutive.
set #x=15;
select distinct t1.date
from
`agenda_specialists` as t1 join
`agenda_specialists` as t2 on
t2.date=t1.date and
t2.begin>=t1.begin and
t2.begin<addtime(t1.begin,sec_to_time(#x*60))
group by t1.id
having count(*)=#x/5
http://sqlfiddle.com/#!2/54d9f6/50
User variables are very useful in mysql
SELECT date,MIN(CASE WHEN BEGIN!='00:00:00' THEN BEGIN END) m,
MAX(CASE WHEN END!='00:00:00' THEN END END) mm
FROM
( SELECT BEGIN,END,date, CASE
WHEN
END = BEGIN +INTERVAL 5 MINUTE THEN #n ELSE #n:=#n+1 END AS g
FROM agenda_specialists,
(SELECT #n:=0) x
ORDER BY id) s
GROUP BY date, g
HAVING ((TIME_TO_SEC(mm) - TIME_TO_SEC(m))/60)>=40
Esentially you want to check if the begin is equal with the end+5 minutes if not you increment a variable you can GROUP BY,it creates the intervals besides the different date.The rest is easy.I had to change the collations,for some reason it gave me illegal mix of collation.Just play with the number at the end.
FIDDLE
Edit:
Run
SHOW VARIABLES LIKE '%char%';
You probably have character_set_server='latin1'
Go into your config file,my.cnf and add or uncomment these lines:
character-set-server = utf8
collation-server = utf8_general_ci
Tested on my machine 5.5