Thread: Merge overlapping time-periods
<div class="WordSection1"><p class="MsoNormal">Hi!<p class="MsoNormal"> <p class="MsoNormal"><span lang="EN-US">AlthoughI try for some time, I am not able to write an SQL-Query that can do the following:</span><p class="MsoNormal"><spanlang="EN-US"> </span><p class="MsoNormal"><span lang="EN-US">I have a very big table (let’s call it“mytable”) with information like this:</span><p class="MsoNormal"><span lang="EN-US"> </span><p class="MsoNormal"><spanlang="EN-US" style="font-size:10.0pt;font-family:"Courier New"">ID BEG END</span><p class="MsoNormal"><spanlang="EN-US" style="font-size:10.0pt;font-family:"Courier New"">1 2000-01-01 2000-03-31</span><pclass="MsoNormal"><span lang="EN-US" style="font-size:10.0pt;font-family:"Courier New"">1 2000-04-01 2000-05-31</span><p class="MsoNormal"><span lang="EN-US" style="font-size:10.0pt;font-family:"Courier New"">1 2000-04-15 2000-07-31</span><p class="MsoNormal"><span lang="EN-US" style="font-size:10.0pt;font-family:"CourierNew"">1 2000-09-01 2000-10-31</span><p class="MsoNormal"><span lang="EN-US"style="font-size:10.0pt;font-family:"Courier New"">2 2000-02-01 2000-03-15</span><p class="MsoNormal"><spanlang="EN-US" style="font-size:10.0pt;font-family:"Courier New"">2 2000-01-15 2000-03-31</span><pclass="MsoNormal"><span lang="EN-US" style="font-size:10.0pt;font-family:"Courier New"">2 2000-04-01 2000-04-15</span><p class="MsoNormal"><span lang="EN-US" style="font-size:10.0pt;font-family:"Courier New"">3 2000-06-01 2000-06-15</span><p class="MsoNormal"><span lang="EN-US" style="font-size:10.0pt;font-family:"CourierNew"">3 2000-07-01 2000-07-15</span><p class="MsoNormal"><span lang="EN-US"> </span><pclass="MsoNormal"><span lang="EN-US">There’s an ID and time periods defined by a start value (BEG)and an end value (END)</span><p class="MsoNormal"><span lang="EN-US"> </span><p class="MsoNormal"><span lang="EN-US">Iwant to merge all periods belonging to the same ID, iff their time periods are overlapping or in a direct sequence.</span><pclass="MsoNormal"><span lang="EN-US"> </span><p class="MsoNormal"><span lang="EN-US">Therefore the resultshould somehow look like this:</span><p class="MsoNormal"><span lang="EN-US"> </span><pre>ID BEG END</pre><pre>1 2000-01-01 2000-07-31</pre><pre>1 2000-09-01 2000-10-31</pre><pre>2 2000-01-15 2000-03-31</pre><pre>2 2000-04-01 2000-04-15</pre><pre>3 2000-06-01 2000-06-15</pre><pre>3 2000-07-01 2000-07-15</pre><pclass="MsoNormal"><span lang="EN-US"> </span><p class="MsoNormal"><span lang="EN-US">I tried using “WITHRECURSIVE” but I didn’t succeed.</span><p class="MsoNormal"><span lang="EN-US"> </span><p class="MsoNormal"><span lang="EN-US">Myserver is PostgreSQL 8.4. Unfortunately I can’t do anything like update or install some fancy module…</span><pclass="MsoNormal"><span lang="EN-US"> </span><p class="MsoNormal"><span lang="EN-US">Thank you for your help!</span><pclass="MsoNormal"><span lang="EN-US"> </span><p class="MsoNormal"><span lang="EN-US">Best regards,</span><pclass="MsoNormal"><span lang="EN-US"> </span><p class="MsoNormal"><span lang="EN-US">Marcel Jira</span></div>
I write a paper on this topic comparing queries for PG, SQL Server and MySQL. Can you read french ? http://blog.developpez.com/sqlpro/p9821/langage-sql-norme/agregation-d-intervalles-en-sql-1/ The worst query is the RECURSIVE one ! A + Le 15/06/2011 17:23, Jira, Marcel a écrit : > Hi! > > Although I try for some time, I am not able to write an SQL-Query that > can do the following: > > I have a very big table (let’s call it “mytable”) with information like > this: > > ID BEG END > > 1 2000-01-01 2000-03-31 > > 1 2000-04-01 2000-05-31 > > 1 2000-04-15 2000-07-31 > > 1 2000-09-01 2000-10-31 > > 2 2000-02-01 2000-03-15 > > 2 2000-01-15 2000-03-31 > > 2 2000-04-01 2000-04-15 > > 3 2000-06-01 2000-06-15 > > 3 2000-07-01 2000-07-15 > > There’s an ID and time periods defined by a start value (BEG) and an end > value (END) > > I want to merge all periods belonging to the same ID, iff their time > periods are overlapping or in a direct sequence. > > Therefore the result should somehow look like this: > > ID BEG END > > 1 2000-01-01 2000-07-31 > > 1 2000-09-01 2000-10-31 > > 2 2000-01-15 2000-03-31 > > 2 2000-04-01 2000-04-15 > > 3 2000-06-01 2000-06-15 > > 3 2000-07-01 2000-07-15 > > I tried using “WITH RECURSIVE” but I didn’t succeed. > > My server is PostgreSQL 8.4. Unfortunately I can’t do anything like > update or install some fancy module… > > Thank you for your help! > > Best regards, > > Marcel Jira > -- Frédéric BROUARD - expert SGBDR et SQL - MVP SQL Server - 06 11 86 40 66 Le site sur le langage SQL et les SGBDR : http://sqlpro.developpez.com Enseignant Arts & Métiers PACA, ISEN Toulon et CESI/EXIA Aix en Provence Audit, conseil, expertise, formation, modélisation, tuning, optimisation *********************** http://www.sqlspot.com *************************
----- Original Message -----From: Jira, MarcelSent: Wednesday, June 15, 2011 4:23 PMSubject: [SQL] Merge overlapping time-periodsHi!
Although I try for some time, I am not able to write an SQL-Query that can do the following:
I have a very big table (lets call it mytable) with information like this:
ID BEG END
1 2000-01-01 2000-03-31
1 2000-04-01 2000-05-31
1 2000-04-15 2000-07-31
1 2000-09-01 2000-10-31
2 2000-02-01 2000-03-15
2 2000-01-15 2000-03-31
2 2000-04-01 2000-04-15
3 2000-06-01 2000-06-15
3 2000-07-01 2000-07-15
Theres an ID and time periods defined by a start value (BEG) and an end value (END)
I want to merge all periods belonging to the same ID, iff their time periods are overlapping or in a direct sequence.
Therefore the result should somehow look like this:
ID BEG END1 2000-01-01 2000-07-311 2000-09-01 2000-10-312 2000-01-15 2000-03-312 2000-04-01 2000-04-153 2000-06-01 2000-06-153 2000-07-01 2000-07-15
I tried using WITH RECURSIVE but I didnt succeed.
My server is PostgreSQL 8.4. Unfortunately I cant do anything like update or install some fancy module
Thank you for your help!
Best regards,
Marcel Jira
2 2000-01-15 2000-03-31
2 2000-04-01 2000-04-15
are in direct sequence (IMHO) as much as
1 2000-01-01 2000-03-31
1 2000-04-01 2000-05-31
are. Isn't my understanding correct?
Best,
Oliveiros
FROM mytable x
LEFT JOIN
(
SELECT a."ID" as xid ,a."BEG" as xbeg,a."END" as xend,b."ID" as yid,b."BEG" as ybeg,b."END" as yend
FROM mytable a
JOIN mytable b
ON a."ID" = b."ID"
AND (( ((a."BEG",a."END") OVERLAPS (b."BEG",b."END"))
OR ((b."BEG" - a."END") = 1))
AND (a."BEG" <> b."BEG")
AND (b."END" <> a."END"))
) y
ON (((yid = x."ID")
AND (ybeg = x."BEG")
AND (yend = x."END"))
OR ((xid = x."ID")
AND (xbeg = x."BEG")
AND (xend = x."END")))
WHERE yid IS NULL)
UNION (
SELECT x."ID",MIN(x."BEG"),MAX(x."END")
FROM mytable x
LEFT JOIN
(
SELECT a."ID" as xid,a."BEG" as xbeg,a."END" as xend,b."ID" as yid,b."BEG" as ybeg,b."END" as yend
FROM mytable a
JOIN mytable b
ON a."ID" = b."ID"
AND (( ((a."BEG",a."END") OVERLAPS (b."BEG",b."END"))
OR ((a."BEG" - b."END") = 1))
AND (a."BEG" <> b."BEG")
AND (b."END" <> a."END"))
) y
ON (((yid = x."ID")
AND (ybeg = x."BEG")
AND (yend = x."END"))
OR ((xid = x."ID")
AND (xbeg = x."BEG")
AND (xend = x."END")))
GROUP BY x."ID"
)
Howdy, Marcel,In the example output you provided the ID = 2 should have just one record...Ain't I right?Best,Oliveiros----- Original Message -----From: Jira, MarcelSent: Wednesday, June 15, 2011 4:23 PMSubject: [SQL] Merge overlapping time-periodsHi!
Although I try for some time, I am not able to write an SQL-Query that can do the following:
I have a very big table (lets call it mytable) with information like this:
ID BEG END
1 2000-01-01 2000-03-31
1 2000-04-01 2000-05-31
1 2000-04-15 2000-07-31
1 2000-09-01 2000-10-31
2 2000-02-01 2000-03-15
2 2000-01-15 2000-03-31
2 2000-04-01 2000-04-15
3 2000-06-01 2000-06-15
3 2000-07-01 2000-07-15
Theres an ID and time periods defined by a start value (BEG) and an end value (END)
I want to merge all periods belonging to the same ID, iff their time periods are overlapping or in a direct sequence.
Therefore the result should somehow look like this:
ID BEG END1 2000-01-01 2000-07-311 2000-09-01 2000-10-312 2000-01-15 2000-03-312 2000-04-01 2000-04-153 2000-06-01 2000-06-153 2000-07-01 2000-07-15
I tried using WITH RECURSIVE but I didnt succeed.
My server is PostgreSQL 8.4. Unfortunately I cant do anything like update or install some fancy module
Thank you for your help!
Best regards,
Marcel Jira