SQL-инструкция для вычисления времени между двумя днями

#mysql #sql

#mysql #sql

Вопрос:

У меня есть таблица базы данных MySQL, где я хочу получить все записи между двумя временными метками. Каждый раз, когда статус меняется, я получаю новую временную метку и новое количество Status .

Что-то вроде этого: Status_List

  Status            Time_Start        Time_End
    2               14:00:12          14:13:33
    5               14:13:33          15:33:41
    9               15:33:41          16:02:11
  

Когда я ищу:

 select * from Status_List where Time_Start between (15:00:00 and 16:00:00)
  
 Output: 9  15:33:41  16:02:11
  

Но мне нужно:

 Output: 5 15:00:00  15:33:41
        9 15:33:41  16:00:00
  

Возможно ли это?

Комментарии:

1. Вы выбираете по Time_Start столбцу, там нет 15:00:00 значения, поэтому результат, который вы получаете, правильный.

2. я это знаю. Но мне также нужны 33: 41 минуты для статуса

3. Здесь нет дней !?!

Ответ №1:

Вы можете использовать запрос, подобный этому:

 SELECT 
    Status
    ,CAST(GREATEST('15:00:00',Time_Start) AS TIME(0)) as Time_Start
    , Time_end
FROM Status_List
WHERE 
    Time_Start BETWEEN '15:00:00' AND '16:00:00'
OR  
    Time_start < '15:00:00' AND Time_End > '15:00:00';
  

пример

 MariaDB [test]> SELECT 
    -> Status
    -> ,CAST(GREATEST('15:00:00',Time_Start) AS TIME(0)) as Time_Start
    -> , Time_end
    -> FROM Status_List
    -> WHERE 
    -> Time_Start BETWEEN '15:00:00' AND '16:00:00'
    -> OR  
    -> Time_start < '15:00:00' AND Time_End > '15:00:00';
 -------- ------------ ---------- 
| Status | Time_Start | Time_end |
 -------- ------------ ---------- 
|      5 | 15:00:00   | 15:33:41 |
|      9 | 15:33:41   | 16:02:11 |
 -------- ------------ ---------- 
2 rows in set (0.001 sec)

MariaDB [test]> 
  

Комментарии:

1. Это также ошибочно включало бы запись с 17:00:00 до 18:00:00: dbfiddle.uk /…

2. привет, спасибо. Это работает отлично. Я пытаюсь вычислить время с 15:00: 00 до 15: 33: 41. поэтому я добавляю: ,ПРИВЕДЕНИЕ(НАИБОЛЬШЕЕ(’15:00:00′, Time_Start) КАК TIME(0)) как Time_Start -> , Time_end, timediff (Time_end, Time_Start) как timeOfStatus. Но впервые я получаю все время. Не время с 15:00:00. есть идеи для этого?

3. используйте это: timediff(Time_end, НАИБОЛЬШЕЕ(’15:00:00′,Time_Start) ) в качестве timeOfStatus

4. ты потрясающий! Спасибо

5. Это отлично работает. Но у меня возникли некоторые проблемы с моей последней строкой. Я вижу статус 3: 19: 43, но он должен закончиться в 20:00 (панель закрыта), но у меня проблемы со временем. Я ожидаю 13 минут, но я получаю timediff для следующего статуса утром в 07:00. Как я могу ограничить время переменным временем (в лучшем случае моим end_time, которое я ищу)

Ответ №2:

С ОБЪЕДИНЕНИЕМ ВСЕХ:

 set @start = '15:00:00', @end = '16:00:00';

select status, @start start, time_end end from status_list
where time_start = 
  (select max(time_start) from status_list where time_start <= @start)
union all
select status, time_start, time_end from status_list
where time_start > @start and time_end < @end 
union all
select status, time_start, @end from status_list
where time_end = 
  (select min(time_end) from status_list where time_end >= @end)
  

Смотрите демонстрацию.
Результаты:

 | status | start    | end      |
| ------ | -------- | -------- |
| 5      | 15:00:00 | 15:33:41 |
| 9      | 15:33:41 | 16:00:00 |
  

Ответ №3:

Если я правильно понял, вы хотите получить строки, в которых либо начало находится в диапазоне, либо конец. Чтобы отсечь значения, выходящие за пределы диапазона, вы можете использовать CASE выражение.

 SELECT status,
       CASE
         WHEN time_start < '15:00:00' THEN
           '15:00:00'
         ELSE
           time_start
       END time_start,
       CASE
         WHEN time_end > '16:00:00' THEN
           '16:00:00'
         ELSE
           time_end
       END time_end
       FROM status_list
       WHERE time_start >= '15:00:00'
             AND time_start < '16:00:00'
              OR time_end >= '15:00:00'
                 AND time_end < '16:00:00';
  

db<> скрипта

Комментарии:

1. Нет необходимости проверять time_end в последней строке. time_end может быть меньше 16:00 и start_time < 15:00, только 1 строка вернет

2. @BerndBuffen: Не приведет ли исключение последнего выражения к включению периода, скажем, с 17:00 до 18:00? Как 18:00 > = 15:00…