I'm trying to get one row for each hour of the day, which I intent to left join certain data to.
I need selected the 00:01:00 and 23:59:00 interval hour for each day.
I have tried this solution but I can't selected 00:01:00 and 23:59:00 interval hour but only 00:00:00 and 23:00:00 interval hour.
How to do resolve this ?
Can you help me please ?
Thank you in advance or any help.
mysql> SELECT CONCAT(CURDATE(),' ','00:00') + INTERVAL (d0*10+d1) hour AS mydate
FROM (
SELECT 0 AS d0 UNION SELECT 1 UNION SELECT 2
) AS t1
cross JOIN (
SELECT 0 AS d1 UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION
SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9 ) AS t2
WHERE (d0*10+d1) < 24
order by d0,d1;
+---------------------+
| mydate |
+---------------------+
| 2020-03-10 00:00:00 |
| 2020-03-10 01:00:00 |
| 2020-03-10 02:00:00 |
| 2020-03-10 03:00:00 |
| 2020-03-10 04:00:00 |
| 2020-03-10 05:00:00 |
| 2020-03-10 06:00:00 |
| 2020-03-10 07:00:00 |
| 2020-03-10 08:00:00 |
| 2020-03-10 09:00:00 |
| 2020-03-10 10:00:00 |
| 2020-03-10 11:00:00 |
| 2020-03-10 12:00:00 |
| 2020-03-10 13:00:00 |
| 2020-03-10 14:00:00 |
| 2020-03-10 15:00:00 |
| 2020-03-10 16:00:00 |
| 2020-03-10 17:00:00 |
| 2020-03-10 18:00:00 |
| 2020-03-10 19:00:00 |
| 2020-03-10 20:00:00 |
| 2020-03-10 21:00:00 |
| 2020-03-10 22:00:00 |
| 2020-03-10 23:00:00 |
+---------------------+
24 rows in set
Edit 01
I need this result :
+---------------------+---------------------+
| start_date | end_date |
+---------------------+---------------------+
| 2020-03-10 00:01:00 | 2020-03-10 01:00:00 |
| 2020-03-10 01:01:00 | 2020-03-10 02:00:00 |
| 2020-03-10 02:01:00 | 2020-03-10 03:00:00 |
| 2020-03-10 03:01:00 | 2020-03-10 04:00:00 |
| 2020-03-10 04:01:00 | 2020-03-10 05:00:00 |
| 2020-03-10 05:01:00 | 2020-03-10 06:00:00 |
| 2020-03-10 06:01:00 | 2020-03-10 07:00:00 |
| 2020-03-10 07:01:00 | 2020-03-10 08:00:00 |
| 2020-03-10 08:01:00 | 2020-03-10 09:00:00 |
| 2020-03-10 09:01:00 | 2020-03-10 10:00:00 |
| 2020-03-10 10:01:00 | 2020-03-10 11:00:00 |
| 2020-03-10 11:01:00 | 2020-03-10 12:00:00 |
| 2020-03-10 12:01:00 | 2020-03-10 13:00:00 |
| 2020-03-10 13:01:00 | 2020-03-10 14:00:00 |
| 2020-03-10 14:01:00 | 2020-03-10 15:00:00 |
| 2020-03-10 15:01:00 | 2020-03-10 16:00:00 |
| 2020-03-10 16:01:00 | 2020-03-10 17:00:00 |
| 2020-03-10 17:01:00 | 2020-03-10 18:00:00 |
| 2020-03-10 18:01:00 | 2020-03-10 19:00:00 |
| 2020-03-10 19:01:00 | 2020-03-10 20:00:00 |
| 2020-03-10 20:01:00 | 2020-03-10 21:00:00 |
| 2020-03-10 21:01:00 | 2020-03-10 22:00:00 |
| 2020-03-10 22:01:00 | 2020-03-10 23:00:00 |
| 2020-03-10 23:01:00 | 2020-03-10 23:59:00 |
+---------------------+---------------------+
You seem to be trying to generate a hours table. If so, I would recommend outputing two columns: one for the lower bound of the interval (which will be inclusive), the other for the upper bound (which should be exclusive)
SELECT
CURRENT_DATE + INTERVAL (d0 * 10 + d1) hour AS start_date,
CURRENT_DATE + INTERVAL (d0 * 10+d1 + 1) hour AS end_date
FROM (SELECT 0 AS d0 UNION SELECT 1 UNION SELECT 2) AS t1
CROSS JOIN (
SELECT 0 AS d1 UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION
SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9
) AS t2
WHERE (d0 * 10 + d1) < 24
ORDER BY d0,d1;
This produces a resultset like:
start_date | end_date :------------------ | :------------------ 2020-03-10 00:00:00 | 2020-03-10 01:00:00 2020-03-10 01:00:00 | 2020-03-10 02:00:00 2020-03-10 02:00:00 | 2020-03-10 03:00:00 ... 2020-03-10 21:00:00 | 2020-03-10 22:00:00 2020-03-10 22:00:00 | 2020-03-10 23:00:00 2020-03-10 23:00:00 | 2020-03-11 00:00:00
You can then join that with your original table with half-open interval, like so:
SELECT ...
FROM myintervals i
LEFT JOIN mytable t
ON t.date >= i.start_date and t.date < i.end_date
The upside of this approach is that it properly handles the first and last minute of each interval.
Edit: to generate your exact desired results, you can do:
SELECT
CURRENT_DATE
+ INTERVAL (d0 * 10 + d1) hour
+ INTERVAL 1 minute AS start_date,
CURRENT_DATE
+ INTERVAL (d0 * 10+d1 + 1) hour
- INTERVAL (case when d0 * 10+d1 = 23 THEN 1 ELSE 0 END) minute AS end_date
FROM (SELECT 0 AS d0 UNION SELECT 1 UNION SELECT 2) AS t1
CROSS JOIN (
SELECT 0 AS d1 UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION
SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9
) AS t2
WHERE (d0 * 10 + d1) < 24
ORDER BY d0,d1;