Запрос Sql для получения диапазона значений

113
12

У меня есть таблица под названием TimeList


  SlotID           SlotStartTime    SlotEndTime
(int identity) (varchar(10)) (varchar(10))
1 8:00AM 8:15AM
2 8:15AM 8:30AM
3 8:30AM 8:45AM
4 8:45AM 9:00AM
5 9:00AM 9:15AM
6 9:15AM 9:30AM
7 9:30AM 9:45AM
8 9:45AM 10:00AM

Если я прохожу SlotStartTime и SlotEndTime, я хочу получить промежутки между ними.
Я использовал следующий запрос для получения временных интервалов в b/w slotStarttime 8:00 AM amd slotEndTime 9:00 AM


select * from TimeList1 where StartTime >='8:00AM' and EndTime <= '9:00AM'

Здесь результат будет следующим:


SlotID     SlotStartTime    SlotEndTime
1 8:00AM 8:15AM
2 8:15AM 8:30AM
3 8:30AM 8:45AM
8 9:45AM 10:00AM

Я хочу получить slotstarttime, начиная с 8:00 и заканчивая 9:00 AM, означает
ожидаемый результат:


SlotID     SlotStartTime    SlotEndTime
1 8:00AM 8:15AM
2 8:15AM 8:30AM
3 8:30AM 8:45AM
4 8:45AM 9:00AM

Какое изменение я должен внести в свой запрос, чтобы получить результат, как указано выше?

спросил(а) 2009-04-03T07:51:00+04:00 11 лет, 5 месяцев назад
1
Решение
97

Попробуйте следующее:

SELECT * 
FROM TimeList1
WHERE (CONVERT(datetime, CONVERT(varchar, GETDATE(), 103) + ' ' + StartTime) >=
CONVERT(datetime, CONVERT(varchar, GETDATE(), 103) + ' ' + '8:00AM'))
AND
(CONVERT(datetime, CONVERT(varchar, GETDATE(), 103) + ' ' + EndTime) <=
CONVERT(datetime, CONVERT(varchar, GETDATE(), 103) + ' ' + '9:00AM'))

ответил(а) 2009-04-03T09:11:00+04:00 11 лет, 5 месяцев назад
41

Часть проблемы, как уже отмечалось, заключается в том, что вы используете строки для представления времени. Другая часть вашей проблемы заключается в том, что нотация AM/PM полностью ужасна для вычислительных целей. Помните, что последовательность:


12:00AM
12:15AM
12:30AM
12:45AM
1:00AM
1:15AM
...
9:45AM
10:00AM
10:15AM
...
11:30AM
11:45AM
12:00PM
12:15PM
12:30PM
12:45PM
1:00PM
1:15PM
...

24-часовое время имеет много достоинств. Если вы использовали:


00:00
00:15
00:30
00:45
01:00
01:15
...
09:45
10:00
10:15
...
11:30
11:45
12:00
12:15
12:30
12:45
13:00
13:15
...

(для одного и того же набора чисел), то ваши строки VARCHAR можно было бы сделать в CHAR (5) и автоматически сортировать по временной последовательности. Вам все равно придется правильно формулировать ваши запросы, включая начальный ноль (ы), в раз меньше 10:00, но значения будут правильно сортироваться и правильно сравнивать.


Некоторые СУБД обеспечивают поддержку подмножеств времени. В IBM Informix Dynamic Server вы можете использовать DATETIME HOUR TO MINUTE в качестве типа для столбца. Это дало бы вам гибкость удаления ведущих нулей.


См. также Конвертировать 12-часовую дату/время в 24-часовую дату/время.

ответил(а) 2009-04-03T08:17:00+04:00 11 лет, 5 месяцев назад
41

Ваш запрос верен. Но это неправильные типы данных.


10:00 действительно приходит до 9:00, учитывая, что они являются строковыми, а не значениями datetime.


Итак, если теперь вы не можете изменить типы данных, лучше всего попробовать этот запрос:


Select * from TimeList1
where StartTime >= Cast('8:00AM' as datetime)
and EndTime <= Cast('9:00AM' as datetime)
//make sure StartTime and EndTime is type of datetime

ответил(а) 2009-04-03T08:07:00+04:00 11 лет, 5 месяцев назад
41

Когда вы используете varchars (или строки на большинстве языков), вы обнаружите, что "10:00" < "9:00" только из-за правил последовательности символов (с "1" < "9").


Вы должны хранить значения даты и времени в столбцах даты и времени. Если вы должны использовать varchars, вам нужно будет преобразовать их в 24-часовой формат фиксированного размера, чтобы сделать это правильно (например, "01:30", "12:15", "18:25" ).


Но мой совет заключается в том, чтобы хранить их как правильные значения даты и времени в DB. Ваши запросы будут проще и быстрее.


Следующее решение может дать вам то, что вы хотите, если я понимаю ваше хранилище данных (одна запись за четверть часа), но мое профессиональное мнение состоит в том, чтобы исправить типы столбцов, поскольку это позволит использовать гораздо более выразительные условия в ваших операторах выбора:


select * from TimeList1
where left(StartTime,1) = '8'
and right(StartTime,2) = 'AM'

ответил(а) 2009-04-03T08:05:00+04:00 11 лет, 5 месяцев назад
40

select * 
from TimeList1
where StartTime >= '8:00AM'
and EndTime <= '9:00AM'

Меньше или равно, не больше или равно.

Хотя на самом деле это не работает, как вы ожидаете, когда ваши столбцы имеют тип varchar. Используйте тип времени или даты.

Первые два абзаца ничего не объясняют, насколько я могу судить. В последнем абзаце содержится непростое объяснение проблемы. - Джонатан Леффлер

В исходном посте, прежде чем вы его отредактировали, OP имел в качестве своего выбора выражение,

select * 
from TimeList1
where StartTime >= '8:00AM'
and EndTime >= '9:00AM'

Я отвечал на это.

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

ответил(а) 2009-04-03T07:54:00+04:00 11 лет, 5 месяцев назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема