MySQL Одна строка для каждого часа 00:01:00 и 23:59:00 интервал дня - PullRequest
1 голос
/ 10 марта 2020

Я пытаюсь получить одну строку для каждого часа дня, к которой я намерен оставить, чтобы присоединиться к определенным данным.

Мне нужно выбрать 00: 01: 00 и 23: 59: 00 интервальный час для каждого дня.

Я пробовал это решение, но не могу выбрать 00: 01: 00 и 23 : 59: 00 интервальный час, но только 00: 00: 00 и 23: 00: 00 интервальный час.

Как решить эту проблему?

Можете ли вы помочь мне, пожалуйста?

Спасибо заранее или любая помощь.

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

Изменить 01

Мне нужно этот результат:

+---------------------+---------------------+
| 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 |
+---------------------+---------------------+

1 Ответ

2 голосов
/ 10 марта 2020

Вы, кажется, пытаетесь создать таблицу часов. Если это так, я бы рекомендовал вывести два столбца: один для нижней границы интервала (который будет включительно), другой для верхней границы (который должен быть исключительным)

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 создает набор результатов, например :

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

Затем вы можете объединить его с исходной таблицей с полуоткрытым интервалом, например:

SELECT ...
FROM myintervals i
LEFT JOIN mytable t 
    ON t.date >= i.start_date and t.date < i.end_date

Преимущество этого подхода что он правильно обрабатывает первую и последнюю минуты каждого интервала.


Редактировать : чтобы получить точные желаемые результаты, вы можете сделать:

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;

Демонстрация на DB Fiddle

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...