tags:

views:

118

answers:

4

Hi everyone,

I know there are lots of these types of questions, but i didn't see one that was similar enough to my criteria. So i'd like to ask for your help please. The fields i have are just start and end which are of time types. I cannot involve any specific dates in this. If the time ranges don't go pass midnight across day, i'd just compare two tuples as such:

end1 > start2 AND start1 < end2

(end points touching are not considered overlapped here.)

But when I involve time range that pass (or at) midnight, this obviously doesn't work. For example, given:

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

Without involving dates, how can i achieve this, please. My assumption is, if end is less than start, then we're involving 2 days.

I'm trying to do this in plain standard SQL, so just a simple and concise logic in the WHERE clause.

Thank you everyone!


Added:

Also, how would I test if one time range completely envelopes another? thanks again!

A: 

use start time and duration (in minutes or whatever unit is appropriate)

Steven A. Lowe
+2  A: 

If your SQL supports time differences:

(end1 - start1) > (start2 - start1) AND (end2 - start2) > (start1 - start2)
Doug Currie
oh this is nifty, thank you! so is the logic that the difference of the start times should be more than the duration?
janechii
duration should always be a positive number, though, i think. so: abs(end1 - start1) > (start2 - start1) AND abs(end2 - start2) > (start1 - start2)
janechii
It is a bit nifty! The derivation came to me via algebra rather than intuition: take your expression, and subtract start1 from both sides of the comparison on the left, and subtract start2 from both sides on the right. This translates to: the duration of event1 must exceed the time between the start of event1 and the start of event2, and the duration of event2 must exceed the time between the start of event2 and the start of event1. The symmetry is pleasing.
Doug Currie
@janechii, re: abs, I am assuming the time difference is "accurate," e.g., using modular arithmetic for start-end
Doug Currie
+1  A: 

Unfortunately, "plain" SQL will be too general to use against an actual database. The reason is that the various database products have different levels of support for calculating the duration between two times. For example, in SQL Server 2008, it would be substantially simpler to convert the time values to DateTime and then do the comparison since many comparison operators are not supported on the Time data type.

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            
Thomas
Yes, you are right, date and time handling seems to differ a lot between databases. I am using PostgreSQL specifically, but this solution is a clever one that should work in PG also. thank you!
janechii
A: 

The program Transtar had this problem. The time data was not associated with any date, nor was the time data in a date time field. The program initially was designed to issue transit itinaries from about 4AM to midnight which worked fine as long as the transit wasn't around the clock. I built a function which did a sliding test for the times so that if you asked for 5AM it would look at times from 1AM to 12:59AM. I wrote it in FORTRAN, but the algorythm would be the same regardless of language.

Dave
Thanks for the suggestion, Dave! I had played around with this idea, but it seems confusing for other maintainers. For an existing system though, this is a nice solution.
janechii
agreed - very confusing - the major thing that must be realized is the time data is modular and the real time is not.
Dave