I have the following relational schema:
dates(date: date, code: char)
code can be ST,MN,MX,ED. An example:
╔════════════╦══════╗
║ date ║ code ║
╠════════════╬══════╣
║ 2001-10-01 ║ ST ║
║ 2001-10-20 ║ ST ║
║ 2001-11-01 ║ MX ║
║ 2001-11-01 ║ MN ║
║ 2001-11-14 ║ MX ║
║ 2001-11-15 ║ ED ║
║ 2001-11-15 ║ MX ║
║ 2001-11-27 ║ MN ║
║ 2001-12-01 ║ ST ║
║ 2001-12-01 ║ ED ║
║ 2001-12-02 ║ MX ║
║ 2001-12-03 ║ MX ║
║ 2001-12-05 ║ ED ║
║ 2001-12-20 ║ ST ║
║ 2001-12-21 ║ MN ║
║ 2001-12-24 ║ MX ║
║ 2001-12-31 ║ ED ║
╚════════════╩══════╝
I need to:
- find any range of dates that starts from one having ST as code and ends with one that has ED as a code.
- in those range there can't be any tuple with ST or ED as a code (the ranges can't overlap).
- do it without procedures and with only one SELECT statement (i can use WITH).
I did part one with the following query:
SELECT DISTINCT ON (dt.date) dt.date AS start, dt1.date AS end
FROM dates AS dt, dates AS dt1
WHERE dt.type='ST' AND dt1.type='ED' AND dt.date<dt1.date;
I can't figure out how to eliminate overlapping ranges though. Using the given example data my query outputs:
╔════════════╦════════════╗
║ start ║ end ║
╠════════════╬════════════╣
║ 2001-10-01 ║ 2001-12-01 ║
║ 2001-10-20 ║ 2001-11-15 ║
║ 2001-12-01 ║ 2001-12-31 ║
║ 2001-12-20 ║ 2001-12-31 ║
╚════════════╩════════════╝
As you can see the second range is overlapping with the first so it's not working as i intended.
The correct output should be:
╔════════════╦════════════╗
║ start ║ end ║
╠════════════╬════════════╣
║ 2001-10-20 ║ 2001-11-15 ║
║ 2001-12-20 ║ 2001-12-31 ║
╚════════════╩════════════╝