SQL обнаруживает перекрытие времени, прошедшего полночь (через 2 дня)

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

end1 > start2 AND start1 < end2

(соприкасающиеся конечные точки здесь не считаются перекрывающимися.)

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

 start  |   end
--------+--------
06:00PM | 01:00AM
03:00PM | 09:00PM

Без дат, как я могу этого добиться, пожалуйста. Я предполагаю, что если конец меньше начала, то мы занимаем 2 дня.

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

Всем спасибо!


Добавлен:

Кроме того, как мне проверить, полностью ли один временной диапазон охватывает другой? еще раз спасибо!


person janechii    schedule 03.05.2010    source источник
comment
@janechii: Добро пожаловать в StackOverflow! Вы можете улучшить свой вопрос, отредактировав теги, чтобы отразить базу данных, которую вы используете (oracle, mysql, sql-server,...)   -  person Peter Lang    schedule 03.05.2010
comment
@janechii - Можете ли вы также показать использование схемы таблицы?   -  person Thomas    schedule 03.05.2010
comment
@Питер - Спасибо. Я специально использую postgresql, но я хотел бы, чтобы он работал и в других БД, пожалуйста.   -  person janechii    schedule 03.05.2010


Ответы (4)


Если ваш SQL поддерживает разницу во времени:

(end1 - start1) > (start2 - start1) AND (end2 - start2) > (start1 - start2)
person Doug Currie    schedule 03.05.2010
comment
о, это прикольно, спасибо! так логика в том, что разница во времени начала должна быть больше, чем продолжительность? - person janechii; 04.05.2010
comment
Однако я думаю, что продолжительность всегда должна быть положительным числом. Итак: абс(конец1 - начало1) › (начало2 - начало1) И абс(конец2 - начало2) › (начало1 - начало2) - person janechii; 04.05.2010
comment
Это немного здорово! Вывод пришел ко мне с помощью алгебры, а не интуиции: возьмите свое выражение и вычтите start1 из обеих сторон сравнения слева и вычтите start2 из обеих сторон справа. Это означает: продолжительность события 1 должна превышать время между началом события 1 и началом события 2, а продолжительность события 2 должно превышать время между началом события 2 и началом события 1. Симметрия радует. - person Doug Currie; 04.05.2010
comment
@janechii, re: abs, я предполагаю, что разница во времени точна, например, используя модульную арифметику для начала-конца - person Doug Currie; 04.05.2010

К сожалению, "простой" SQL будет слишком общим для использования с реальной базой данных. Причина в том, что различные продукты баз данных имеют разные уровни поддержки расчета продолжительности между двумя периодами времени. Например, в SQL Server 2008 было бы значительно проще преобразовать значения времени в DateTime, а затем выполнить сравнение, поскольку многие операторы сравнения не поддерживаются для типа данных Time.

Select ...
From    (
        Select Cast(T.Start1 As DateTime) As Start1
            , Case
                When Cast(T.Start1 As DateTime) > Cast(T.End1 As DateTime) Then DateAdd(d,1,Cast(T.End1 As DateTime))
                Else Cast(T.End1 As DateTime)
                End As End1
        From ...
        ) As T
Where T.End1 > T2.Start2 And T1.Start2 < T2.End2            
person Thomas    schedule 03.05.2010
comment
Да, вы правы, обработка даты и времени сильно различается между базами данных. Я специально использую PostgreSQL, но это умное решение, которое должно работать и в PG. спасибо! - person janechii; 04.05.2010

использовать время начала и продолжительность (в минутах или любых других единицах измерения)

person Steven A. Lowe    schedule 03.05.2010

У программы Transtar была эта проблема. Данные времени не были связаны ни с какой датой, как и данные времени в поле даты и времени. Изначально программа была разработана для выдачи транзитных маршрутов примерно с 4 утра до полуночи, что работало нормально, если транзит не был круглосуточным. Я создал функцию, которая выполняла скользящую проверку времени, чтобы, если вы запросили 5 утра, она просматривала время от 1 до 00:59. Я написал это на FORTRAN, но алгоритм был одинаковым независимо от языка.

person Dave    schedule 03.05.2010
comment
Спасибо за предложение, Дэйв! Я поиграл с этой идеей, но она кажется запутанной для других сопровождающих. Однако для существующей системы это хорошее решение. - person janechii; 04.05.2010
comment
согласен - очень запутанно - главное, что нужно понять, это то, что данные о времени являются модульными, а реальное время - нет. - person Dave; 04.05.2010