I've a table, which describes work slices of a business working calendar: (date format is 24 hours format)
PK | STARTDATE | ENDDATE
__________________________________________
1 | 2012/07/21 02:00 | 2012/07/21 04:00
2 | 2012/07/21 03:00 | 2012/07/21 10:00
3 | 2012/07/21 06:00 | 2012/07/21 17:00
4 | 2012/07/21 18:00 | 2012/07/21 19:00
Now, I like to merge the date ranges (within a given start and end date) like this:
PK | STARTDATE | ENDDATE
__________________________________________
1 | 2012/07/21 02:00 | 2012/07/21 17:00
2 | 2012/07/21 18:00 | 2012/07/21 19:00
Is there a way to do this with SQL97 standard? If so, what is with other operations (e.g. if I want to to an invered merge, the result should be
PK | STARTDATE | ENDDATE
__________________________________________
1 | 2012/07/21 00:00 | 2012/07/21 02:00
2 | 2012/07/21 19:00 | 2012/07/22 00:00
This is my solution.
Based on ErikE response :
This should do the trick in most SQL-92 supporting DBMSes. No advanced SQL Syntax here.
The performance may not be so good because it has to join the same table 4 times. If using DBMS-specific syntax is an option you'll probably be able to get much better performance.
See a Sql Fiddle for this same query working in several different RDBMSes:
Update
Here's a new query that still doesn't do recursion, and only scans the table once. It does have two sorts, which are the most expensive part of the query (88% of the cost in this sample with just a few rows). However, do not underestimate the benefit of doing fewer reads, and not having to join... sometimes queries like this can kick major butt.
Here's an example using SQL Server syntax. First it determines the "heads", or rows that have no previous overlapping rows. To determine the last "child" of a "head", it looks for the last row that is smaller than the next "head". Here's the SQL:
Live example at SQL Fiddle.