Trying to get 24 hours of data from SQL - mysql

I am not very skilled at SQL so hopefully someone here can help me out.
I have a date_of_post column in my table which looks like this (example) 2015-08-31 11:00:00.
I use the INTERVAL 1 DAY to get the last 24 hours. However it returns more than the last 24 hours it seems. This is the query I use to fetch my data
SELECT DATE_ADD(date(t.date_of_post),
INTERVAL hour(t.date_of_post) HOUR) AS dateTime,
count(*) as entries
FROM `soc_stat` t
WHERE `main_tag` = 'morgenmad'
AND t.date_of_post > DATE_SUB(CURDATE(), INTERVAL 1 DAY)
GROUP BY date(t.date_of_post), hour(t.date_of_post)
And it returns the following:
2015-08-31 11:00:00 = 11
2015-08-31 12:00:00 = 2
2015-08-31 13:00:00 = 3
2015-08-31 14:00:00 = 3
2015-08-31 15:00:00 = 1
2015-08-31 16:00:00 = 3
2015-08-31 17:00:00 = 2
2015-08-31 19:00:00 = 1
2015-09-01 04:00:00 = 1
2015-09-01 05:00:00 = 3
2015-09-01 06:00:00 = 9
2015-09-01 07:00:00 = 33
2015-09-01 08:00:00 = 38
2015-09-01 09:00:00 = 29
2015-09-01 10:00:00 = 13
2015-09-01 11:00:00 = 12
2015-09-01 12:00:00 = 6
2015-09-01 13:00:00 = 5
I don't understand why 11:00:00, 12:00:00 and 13:00:00 exist in 2015-08-31 and 2015-09-01. Shouldn't it only return the last 24 hours?

CURDATE() returns the "beginning of today". replace it with NOW()

A visual might help. If you use aliases stick with them throughout. When you use aggregate functions like count, group by all non-aggregate columns.
for me it is 2015-09-01 08:47:00
create table soc_stat
( id int auto_increment primary key,
main_tag varchar(20) not null,
date_of_post datetime not null
);
truncate table soc_stat;
insert soc_stat (main_tag,date_of_post) values ('morgenmad','2015-09-02 11:00:00');
insert soc_stat (main_tag,date_of_post) values ('morgenmad','2015-09-01 11:00:00');
insert soc_stat (main_tag,date_of_post) values ('morgenmad','2015-09-01 09:00:00');
insert soc_stat (main_tag,date_of_post) values ('morgenmad','2015-09-01 08:00:00');
insert soc_stat (main_tag,date_of_post) values ('morgenmad','2015-09-01 07:00:00');
insert soc_stat (main_tag,date_of_post) values ('morgenmad','2015-08-31 09:00:00');
insert soc_stat (main_tag,date_of_post) values ('morgenmad','2015-08-31 08:00:00');
insert soc_stat (main_tag,date_of_post) values ('morgenmad','2015-08-31 07:00:00');
SELECT date(t.date_of_post) dt, hour(t.date_of_post) hr,count(*) as entries
FROM `soc_stat` t
WHERE t.`main_tag` = 'morgenmad'
AND t.date_of_post between DATE_SUB(now(), INTERVAL 1 DAY) and now()
GROUP BY dt,hr
order by t.date_of_post desc;
+------------+------+---------+
| dt | hr | entries |
+------------+------+---------+
| 2015-09-01 | 8 | 1 |
| 2015-09-01 | 7 | 1 |
| 2015-08-31 | 9 | 1 |
+------------+------+---------+

Related

How to get the data only on working hours

Is there a way to select or query the data only on working hours?
id
description
datetime
1
Alarm Activated
2022-01-02 14:00:00
2
Alarm Deactivated
2022-01-02 15:00:00
3
Alarm Activated
2022-01-03 18:00:00
..
Alarm Activated
2022-01-31 11:00:00
I'd like to get the number of the alarm activated on or during working hours from mon-fri 8am to 5pm.
I tried to use the between date but no luck.
SELECT * -- if you need to count them only - use SELECT COUNT(*)
FROM datatable
WHERE WEEKDAY(`datetime`) < 5 -- test weekday
AND TIME(`datetime`) BETWEEN '08:00:00' AND '17:00:00'; -- test hours
Here we use the following tests:
weekday < 6 (Saturday) = Monday to Friday
hour more than 7 (from 08:00:00)
hour less than 17 (to 16:59:59)
create table alarms(
id int,
description varchar(100),
date_time datetime);
insert into alarms values
(1,'Alarm Activated',
'2022-01-02 14:00:00'),
(2,'Alarm Deactivated',
'2022-01-02 15:00:00'),
(3,'Alarm Activated',
'2022-01-03 18:00:00'),
(4,'Alarm Activated',
'2022-01-31 11:00:00');
select *
from alarms
where weekday(date_time) < 6
and 7 < hour(date_time) < 17;
id | description | date_time
-: | :-------------- | :------------------
3 | Alarm Activated | 2022-01-03 18:00:00
4 | Alarm Activated | 2022-01-31 11:00:00
db<>fiddle here

MySQL 5: How to find the peak of customers during working time

I have table in MySQL with times spent by customers and I need to find the most busy 30 mins.
CREATE TABLE Customer
(id int NOT NULL AUTO_INCREMENT PRIMARY KEY,
customerId int NOT NULL,
arrival datetime,
leaving datetime);
INSERT INTO Customer
(customerId, arrival, leaving)
VALUES
(1, '2018-01-01 10:00:00', '2018-01-01 12:00:00'),
(2, '2018-01-01 11:00:00', '2018-01-01 12:00:00'),
(3, '2018-01-01 11:30:00', '2018-01-01 12:30:00'),
(4, '2018-01-01 13:30:00', '2018-01-01 14:30:00')
;
Expected result is something like multiplerows with time and number of customers:
10:00 10:30 1
10:30 11:00 1
11:00 11:30 2
11:30 12:00 3
12:00 12:30 1
I can easily make 5 sql queries and get the result (I made some view in similar problem https://stackoverflow.com/a/59478411/11078894 ), but I do not know how to get the result with 1 query.
Please how to make subintervals in MySQL? Thx
Here is a solution based on union all and window function (available in SQL 8.0) that gets you quite close:
select
dt start_dt,
lead(dt) over(order by dt) end_dt,
sum(sum(cnt)) over(order by dt) cnt
from (
select arrival dt, 1 cnt from Customer
union all
select leaving, -1 from Customer
) t
group by dt
order by dt
The logic is to increment a global counter on each arrival and decrement it on each leave. You can then aggregate and do a window sum.
The only difference with your expected results is that this query does not generate a fixed list of intervals, but instead a list of intervals for which the number of customer is constant, as you can see in this demo:
start_dt | end_dt | cnt
:------------------ | :------------------ | --:
2018-01-01 10:00:00 | 2018-01-01 11:00:00 | 1
2018-01-01 11:00:00 | 2018-01-01 11:30:00 | 2
2018-01-01 11:30:00 | 2018-01-01 12:00:00 | 3
2018-01-01 12:00:00 | 2018-01-02 12:30:00 | 1
2018-01-02 12:30:00 | | 0
Thanks to the post from GMB I found the solution also for the SQL 5
Some view:
CREATE OR REPLACE VIEW changeTimeView AS
select arrival AS changeTime, 1 cnt from Customer
union all
select leaving, -1 from Customer
ORDER BY changeTime
After the view is created:
SELECT DISTINCT chT2.changeTime, (SELECT SUM(chT1.cnt) FROM changeTimeView chT1 WHERE TIMEDIFF(chT1.changeTime,chT2.changeTime)<=0) FROM changeTimeView chT2
Result:
2018-01-01 10:00:00 1
2018-01-01 11:00:00 2
2018-01-01 11:30:00 3
2018-01-01 12:00:00 1
2018-01-01 12:30:00 0
2018-01-01 13:30:00 1
2018-01-01 14:30:00 0

How to select count today and tomorrow data less than specific time group by day?

I have a table like a table below.
I want to select count and group by day.
But the data in 1 day will start counts at 7:00:00 until tomorrow at 6:59:59 (24hr.).
For example
Day 1 data between '2019/06/01 7:00:00' and '2019/06/02 06:59:59'
Day 2 data between '2019/06/02 7:00:00' and '2019/06/03 06:59:59'
How can I code the where condition?
id | create_date | judge |
-----+---------------------+---------+
1 | 2019-06-02 8:00:00 | ok |
2 | 2019-06-02 9:00:00 | ok |
3 | 2019-06-02 10:00:00 | ok |
4 | 2019-06-02 11:00:00 | ok |
5 | 2019-06-02 15:00:00 | ok |
6 | 2019-06-03 4:00:00 | ok |
7 | 2019-06-03 5:00:00 | ok |
8 | 2019-06-03 8:00:00 | ok |
9 | 2019-06-03 9:00:00 | ok |
10 | 2019-06-03 9:00:00 | fail |
I've tried below but the result is not as expected.
SELECT COUNT(*),DAY(create_date)
FROM mytable
WHERE judge = 'ok' and MONTH(create_date) = '6' and YEAR(create_date) = '2019' and TIME(create_date) > '07:00:00'
Group by DAY(create_date) order by DAY(create_date) ASC
Expected results
COUNT(*) | DAY(create_date) |
-----------+---------------------+
7 | 2 | (from id 1 to 7)
2 | 3 | (from id 8 and 9)
You could subtract seven hours from each date, truncate them to show the date only and then group them:
SELECT DATE(DATE_SUB(create_date, INTERVAL 7 HOUR)), COUNT(*)
FROM mytable
-- Where clause if you need it...
GROUP BY DATE(DATE_SUB(create_date, INTERVAL 7 HOUR))
Just subtract 7 hours for the aggregation and the date/time comparisons:
SELECT DATE(create_date - interval 7 hour) as dte, COUNT(*)
FROM mytable
WHERE judge = 'ok' and
create_date >= '2019-06-01 07:00:00' AND
create_date < '2019-07-01 07:00:00'
GROUP BY DATE(create_date - interval 7 hour)
ORDER BY dte;
Try this-
SELECT
CAST(DATE_SUB(create_date, INTERVAL 7 HOUR) AS DATE),
COUNT(*)
FROM YOUR_TABLE
GROUP BY CAST(DATE_SUB(create_date, INTERVAL 7 HOUR) AS DATE)

Find number of records in a date range

table : booked_timings
id | from date | todate | vehicle id
------------------------------------------------------------------
1 2017-05-04 06:00:00 2017-05-04 08:00:00 98
2 2017-05-04 10:00:00 2017-05-04 12:00:00 98
3 2017-05-04 15:00:00 2017-05-04 18:30:00 98
Above table consists of the booked timings of vehicle with id 98. I need an MySQL query to list out all the booked timings for vehicle with id 98 when user tries to book in following timings
(i) 08:00:00 to 12:00:00
(ii) 05:00:00 to 23:00:00
SELECT * FROM TABLE WHERE 1=1 AND
(
(
STR_TO_DATE(DATE_FORMAT(FROMDATE,'%H:%i:%s'),'%H:%i:%s') > STR_TO_DATE(08:00:00,'%H:%i:%s') AND STR_TO_DATE(DATE_FORMAT(FROMDATE,'%H:%i:%s'),'%H:%i:%s') < STR_TO_DATE(12:00:00,'%H:%i:%s')
)
OR
(
STR_TO_DATE(DATE_FORMAT(FROMDATE,'%H:%i:%s'),'%H:%i:%s') > STR_TO_DATE(05:00:00,'%H:%i:%s') AND STR_TO_DATE(DATE_FORMAT(FROMDATE,'%H:%i:%s'),'%H:%i:%s') < STR_TO_DATE(23:00:00,'%H:%i:%s')
)
)
As shown in above code,assuming that fromdate and todate are COLUMN with DATE datatype.And comparing only time fraction of that column with time duration which specified by you.Again here we provide string,so we need to convert this string to date using
STR_TO_DATE()function.
Try above code,hope this will helps.

SQL query find dates in range of relation to another date

I am trying query and table to find a incident opened date that is within 2 weeks after a user start date.
I have a table like this
ID | StartDate | OpenedDate
---|-------------------------|---------------------
1 | 2014-01-02 05:44:47.000 | 2014-01-14 00:00:00.000
2 | 2011-01-02 13:35:01.000 | 2012-07-09 00:00:00.000
3 | 2011-01-02 13:35:01.000 | 2011-01-10 00:00:00.000
4 | 2011-01-02 13:35:01.000 | 2012-07-09 00:00:00.000
5 | 2011-01-02 13:35:01.000 | 2012-07-09 00:00:00.000
I would only want lines 1 and 3 since StartDate is within 2 weeks of the opendate
Try this:
SELECT
ID,
StartDate,
OpenedDate
FROM
mytable
WHERE
OpenedDate >= DATEADD(d, -14, StartDate)
SELECT
ID,
StartDate,
OpenedDate
FROM
mytable
WHERE
datediff(wk,getdate(),startdate)<=2