Я думаю, @gbn тебе не поможет. Я постараюсь заполнить.
Дано - таблица с именем timedata, диапазоны которой превышают не более одного дня
WITH normalized AS
(
SELECT *
FROM timedata
WHERE datepart(day,start_time) = datepart(day,endtime)
UNION ALL
SELECT id, rate, start_time, dateadd(second,dateadd(day,datediff(day,0,end_time),0),-1) as end_time
FROM timedata
WHERE not (datepart(day,start_time) = datepart(day,endtime))
UNION ALL
SELECT id, rate,dateadd(day,datediff(day,0,end_time),0) as start_time, end_time
FROM timedata
WHERE not (datepart(day,start_time) = datepart(day,endtime))
)
SELECT *
FROM normalized
WHERE datepart(hour,start_time) < @inhour
AND datepart(hour,end_time) > @inhour
Это использует CTE и трюк для усечения значений даты и времени. Чтобы понять этот трюк, прочитайте этот вопрос и ответ: Пол даты в SQL-сервере
Вот краткое описание того, что делает этот запрос:
Создать нормализованную таблицу с каждым интервалом времени, превышающим один день, на
- Выбор всех строк, которые встречаются в один и тот же день.
Тогда для каждой записи, которая охватывает два дня, присоединяясь к
- Выбор времени начала и одной секунды до следующего дня в качестве времени окончания всего этого промежутка.
и
- Выбор 12:00 даты окончания в качестве времени начала и времени окончания.
Наконец, вы выполняете выбор, используя индикатор часов на этой нормализованной таблице.
Если ваши диапазоны превышают один день, вам понадобится рекурсивный CTE для получения той же нормализованной таблицы.