Select rows from 6 am to 6 am - mysql

Help create a query that will select records from the table for the past period from 6AM until 6AM, the table has a timestamp field.
I will explain, for example:
Now: 2019-06-15 04:44:42
Period: 2019-06-13 06:00:00 - 2019-06-14 06:00:00
Now: 2019-06-15 07:44:42
Period: 2019-06-14 06:00:00 - 2019-06-15 06:00:00
Now: 2019-06-16 01:44:42
Period: 2019-06-14 06:00:00 - 2019-06-15 06:00:00
I think I was not the easiest request:
SELECT * FROM `table` WHERE `timestamp`
BETWEEN
DATE_ADD(DATE(NOW() - INTERVAL '1 6' DAY_HOUR), INTERVAL 6 HOUR)
AND
DATE_ADD(DATE(NOW() - INTERVAL '0 6' DAY_HOUR), INTERVAL 6 HOUR);
How simpler?

You can get the upper range limit with:
date(now() - INTERVAL 6 HOUR) + INTERVAL 6 HOUR
The lower limit would be exactly one day (24 hours) earlier:
date(now() - INTERVAL 6 HOUR) + INTERVAL 6 HOUR - INTERVAL 1 day
So your query could be:
SELECT *
FROM `table` t
WHERE t.timestamp >= date(now() - INTERVAL 6 HOUR) + INTERVAL 6 HOUR - INTERVAL 1 day
AND t.timestamp < date(now() - INTERVAL 6 HOUR) + INTERVAL 6 HOUR
But to avoid code duplication I would rewrite it to:
SELECT t.*
FROM `table` t
CROSS JOIN (
SELECT date(now() - INTERVAL 6 HOUR) + INTERVAL 6 HOUR as upper_limit
) r -- r for "range"
WHERE t.timestamp >= r.upper_limit - INTERVAL 1 day
AND t.timestamp < r.upper_limit
You can though use <= r.upper_limit instead of < r.upper_limit to get the same result as with BETWEEN.

SELECT start, start +interval 24 hour end
FROM ( SELECT date(now())
- interval if(hour(now())>6, 1, 2) day
+ interval 6 hour
as start
) dates;

Related

How do I get the last 24hours in 24 rows from now?

For example my datetime is 2019/29/08 16:47
My table looks like this
ID stuff timestamp
1 ... 2019/29/08 16:47
2 ... 2019/29/08 16:45
3 ... ...
50 ... 2019/29/08 15:47
... ... ...
100 ... 2019/29/08 14:47
How do I select only the rows, that are 1h, 2h, 3h, .. ,24h before now?
to get something like
ID stuff timestamp
1 ... 2019/29/08 15:47
2 ... 2019/29/08 14:47
3 ... 2019/29/08 13:47
.. ... ...
24 ... 2019/28/08 16:47
SELECT *
FROM YourTable
WHERE timestamp IN ( NOW() - INTERVAL 1 HOUR,
NOW() - INTERVAL 2 HOUR,
NOW() - INTERVAL 3 HOUR,
NOW() - INTERVAL 4 HOUR,
NOW() - INTERVAL 5 HOUR,
NOW() - INTERVAL 6 HOUR,
NOW() - INTERVAL 7 HOUR,
NOW() - INTERVAL 8 HOUR,
NOW() - INTERVAL 9 HOUR,
NOW() - INTERVAL 10 HOUR,
NOW() - INTERVAL 11 HOUR,
NOW() - INTERVAL 12 HOUR,
NOW() - INTERVAL 13 HOUR,
NOW() - INTERVAL 14 HOUR,
NOW() - INTERVAL 15 HOUR,
NOW() - INTERVAL 16 HOUR,
NOW() - INTERVAL 17 HOUR,
NOW() - INTERVAL 18 HOUR,
NOW() - INTERVAL 19 HOUR,
NOW() - INTERVAL 20 HOUR,
NOW() - INTERVAL 21 HOUR,
NOW() - INTERVAL 22 HOUR,
NOW() - INTERVAL 23 HOUR,
NOW() - INTERVAL 24 HOUR)

MySQL - SELECT rows between Yesterday 3pm and Today 7:30am

I'm trying to return rows between yesterday 15:00 and today 07:30, but can't seem to get it work.
I've tried the following two methods, but they haven't worked.
Note:
Getdate() should be CURDATE() in MySQL
TIMESERIAL is denied to my user account in the database
Code Examples:
where dateadd(dd, datediff(dd,0,Getdate()),0)- 1
and dateadd(dd, datediff(dd,0,Getdate()),0)- 1) + '23:59:59'
where [Table].[Date Time] Between Date()-1 + TimeSerial(18,0,0)
And Date() + TimeSerial(18,0,0)
you need to use the DATE_ADD and then INTERVAL n HOUR OR MINUTE.
Please check the attached fiddle. http://rextester.com/JIXU4144
select DATE_ADD(current_date, INTERVAL -9 HOUR);
select DATE_ADD(current_date, INTERVAL 450 minute);
select * from temp
where createdOn between '2018-08-28 15:00:00' and '2018-08-29 07:30:00';
select * from temp
where createdOn between DATE_ADD(current_date, INTERVAL -9 HOUR) and DATE_ADD(current_date, INTERVAL 450 minute)
If you are using MySQL, you can do:
where col >= curdate() - interval 1 day + interval 15 hour and
col < curdate() + interval 7.5 * 60 minute
You can also write this a bit more readably as:
where col >= curdate() - interval 1 day + interval 15 hour and
col < curdate() + interval '7:30' hour_minute

MySQL - Get Aggregates For Last 1 Day, 7 Days, 30 Days And Allow For Records To Be Counted In More Than 1 Group

I have a table with the following data:
I am looking to group the rows into the following:
Within the last day (everything within the last 24 hours)
Within the last 7 days (everything within the last week)
Within the last 30 days (everything within the last month)
The end result for the above rows would look something like:
I can group the records into these brackets right now with:
SELECT (CASE WHEN created_at = CURDATE() THEN '1 Day'
WHEN created_at >= CURDATE() - INTERVAL 6 DAY THEN '7 Days'
WHEN created_at >= CURDATE() - INTERVAL 29 DAY THEN '30 Days'
END) AS Timeframe, COUNT(*) AS Count
FROM my_table
GROUP BY (CASE WHEN created_at = CURDATE() THEN '1 Day'
WHEN created_at >= CURDATE() - INTERVAL 6 DAY THEN '7 Days'
WHEN created_at >= CURDATE() - INTERVAL 29 DAY THEN'30 Days'
END)
But this will prevent individual records from being counted more than once. For example, lines 2 and 3 in the first picture needs to be counted in all three brackets (1 day, 7 days, and 30 days) - while lines 6 through 9 only needs to be counted in the 30 days bracket.
How would you do this with MySQL?
It is easiest to do this as columns, rather than rows:
SELECT SUM(created_at = CURDATE()) as today
SUM(created_at >= CURDATE() - INTERVAL 6 DAY) as last_7_days,
SUM(created_at >= CURDATE() - INTERVAL 29 DAY) as last_30_days,
SUM(created_at < CURDATE() - INTERVAL 29 DAY) as older
FROM my_table;
If you want your response in several rows, instead of just one with several columns, take #Gordon Linoff as your starting point... but perform the queries "one row at at time" (it won't be as efficient, because you visit the table 4 times instead of 1!):
-- Row for the 1 day timeframe
SELECT '1 Day' AS `Timeframe`, SUM(created_at = CURDATE()) AS `Count`
FROM my_table
UNION
-- Row for the 7 days timeframe...
SELECT '7 Days' AS `Timeframe`, SUM(created_at >= CURDATE() - INTERVAL 6 DAY) AS `Count`
FROM my_table
UNION
SELECT '30 Days' AS `Timeframe`, SUM(created_at >= CURDATE() - INTERVAL 29 DAY) AS `Count`
FROM my_table
UNION
SELECT 'Older' AS `Timeframe`, SUM(created_at < CURDATE() - INTERVAL 29 DAY) AS `Count`
FROM my_table ;
If you can use MariaDB instead of MySQL, you can use a WITH, which will allow the query to be efficient again:
WITH stats AS
(
SELECT SUM(created_at = CURDATE()) as today,
SUM(created_at >= CURDATE() - INTERVAL 6 DAY) as last_7_days,
SUM(created_at >= CURDATE() - INTERVAL 29 DAY) as last_30_days,
SUM(created_at < CURDATE() - INTERVAL 29 DAY) as older
FROM my_table
)
-- Convert to rows with negligible overhead
SELECT '1 Day' AS `Timeframe`, today FROM stats
UNION
SELECT '7 Days', last_7_days FROM stats
UNION
SELECT '30 Days', last_30_days FROM stats
UNION
SELECT 'Older', older FROM stats ;
In both cases, you'll get (as of 2017-07-25):
Timeframe | today
:-------- | ----:
1 Day | 0
7 Days | 4
30 Days | 8
Older | 0
dbfiddle here

Query data in an specified interval

I am trying to query a timesheet where time span (cycle) is 21 to 20, thus today (10/30/2014) is November.
So, 10/14/2014 is October.
2014-09-21 and 2014-10-20 is one time span
2014-10-21 and 2014-11-20 is one time span
The table is simply storing the date for the timesheet:
id date hours
So, I can specifically say:
SELECT * FROM rapoarte WHERE DATE(ziua) BETWEEN "2014-09-21" AND "2014-10-20"
But I can't figure out how to:
How can I query through this interval for say 1 year (or more)
How can I query for this month?
dynamically
The easiest way is to do date arithmetic. So, for October, you would use:
SELECT *
FROM rapoarte
WHERE month(DATE(ziua) - interval 20 day + interval 1 month) = 10
The idea is to subtract 20 days and add a month. This seems to be the logic for the reporting month.
You can add this as a field:
SELECT *,
date_format(month(DATE(ziua) - interval 20 day + interval 1 month), '%Y-%m') as ReportingMonth
FROM rapoarte
WHERE month(DATE(ziua) - interval 20 day + interval 1 month) = 10
EDIT:
If you want data for this reporting month:
WHERE month(DATE(ziua) - interval 20 day + interval 1 month) = month(DATE(now()) - interval 20 day + interval 1 month) and
year(DATE(ziua) - interval 20 day + interval 1 month) = year(DATE(now()) - interval 20 day + interval 1 month)

SQL Hourly Data

The query below retrieves weather data from a MySql database, and groups this data in to an hourly format.
select hour(datetime) AS hour
, avg(Temperature) as AVGT
from Database.minute
WHERE DATETIME
BETWEEN (CURDATE() + INTERVAL (SELECT hour(NOW())) hour - INTERVAL 23 hour)
AND ((CURDATE() + INTERVAL (SELECT hour(NOW())) hour))
group by hour
order by (CURDATE() + INTERVAL (SELECT hour(NOW())) hour - INTERVAL 23 hour)
Output is as follows:
hour AVGT
19 11.730
20 11.970
21 11.970
22 11.760
23 11.660
0 11.700
1 11.830
2 12.370
3 12.770
4 12.840
5 12.840
6 12.540
7 12.500
8 12.030
9 12.100
10 12.300
11 12.060
12 11.090
13 10.920
14 10.920
15 10.820
16 10.760
17 10.690
18 10.560
The time is now 18:15. All of the above output is correct apart from the data gathered for hour '18'. Instead of getting the average value between 18:00 and 18:15, it just outputs the average at time 18:00. ie. ignoring data between 18:01 and 18:14.
How can I modify the above query to include data in the current hour (18:00 to Now)?
Thanks
Why don't you simply try
SELECT Hour(datetime) AS hour,
Avg(temperature) AS AVGT
FROM DATABASE.minute
WHERE datetime BETWEEN ( Curdate() + INTERVAL (SELECT Hour(Now())) hour -
INTERVAL 23 hour ) AND Now()
GROUP BY hour
ORDER BY ( Curdate() + INTERVAL (SELECT Hour(Now())) hour - INTERVAL 23 hour )
I agree with #Ankur's answer (your filter citerion should not filter records up to the current hour, but rather the current time), however your date/time operations are very strange:
You don't need a subquery (SELECT Hour(NOW())) to obtain HOUR(NOW());
You can express ( Curdate() + INTERVAL (SELECT Hour(NOW())) hour - INTERVAL 23 hour ) more simply:
CURDATE() + INTERVAL HOUR(NOW()) - 23 HOUR
Or, in my view, more clearly:
DATE_FORMAT(NOW() - INTERVAL 23 HOUR, '%Y-%m-%d %H:00:00')
Your ORDER BY clause is a constant and therefore achieves nothing: did you mean to order by hour?
Therefore:
SELECT HOUR(datetime) AS hour,
AVG(Temperature) AS AVGT
FROM Database.minute
WHERE datetime BETWEEN
DATE_FORMAT(NOW() - INTERVAL 23 HOUR, '%Y-%m-%d %H:00:00')
AND NOW()
GROUP BY hour
ORDER BY hour