#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';
Комментарии:
1. Нет необходимости проверять time_end в последней строке. time_end может быть меньше 16:00 и start_time < 15:00, только 1 строка вернет
2. @BerndBuffen: Не приведет ли исключение последнего выражения к включению периода, скажем, с 17:00 до 18:00? Как 18:00 > = 15:00…