I have Work
and Person
tables (these are just examples to understand problem).
Structure
Work
table
id INTEGER
person_id INTEGER
dt_from DATETIME
dt_to DATETIME
Person
table
person_id INTEGER
name VARCHAR(50)
Data
Work
table
id | person_id | dt_from | dt_to
-------------------------------------------------
1 | 1 | 2011-01-01 | 2011-02-02
2 | 1 | 2011-02-02 | 2011-04-04
3 | 1 | 2011-06-06 | 2011-09-09
4 | 2 | 2011-01-01 | 2011-02-02
5 | 2 | 2011-02-02 | 2011-03-03
....etc.
Person
table
Just person names with person id
Expected output
Person 1 : 2011-01-01 - 2011-04-04
Person 1 : 2011-06-06 - 2011-09-09
Person 2 : 2011-01-01 - 2011-03-03
Interval must be in sequence. It cannot be broken somewhere in middle. Thats why Person 1 have two intervals.
I'm using postgres if it changes something. Have you any thougths? I wanted do it in one query, but if there is no such solution i will do some interval merge in php.
You could try postgres's WITH RECURSIVE construct. (after all, a linked list is a kind of tree) Getting the boundary conditions right will be a problem, but at least it would solve the problem without the need for loops.
UPDATE: Added code. The problem with RECURSIVE is that you can only specify only the "tail" boundary condition. To specify the "head" condition, you need to wrap it into a view.
-- now generate some data with gaps
The resulting query plan looks perfect:
There may be a way to do this in one SQL select, but it escapes me. I managed to do it with one stored function though. Here's what I did for my testing:
Then
returned this result:
which is, I think, what you're after.