Обсуждение: Merge overlapping time-periods

Поиск
Список
Период
Сортировка

Merge overlapping time-periods

От
"Jira, Marcel"
Дата:
<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>

Re: Merge overlapping time-periods

От
"F. BROUARD / SQLpro"
Дата:
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 *************************



Re: Merge overlapping time-periods

От
"Oliveiros d'Azevedo Cristina"
Дата:
Howdy, Marcel,
 
In the example output you provided the ID = 2 should have just one record...Ain't I right?
 
Best,
Oliveiros
----- Original Message -----
Sent: Wednesday, June 15, 2011 4:23 PM
Subject: [SQL] Merge overlapping time-periods

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

Re: Merge overlapping time-periods

От
"Oliveiros d'Azevedo Cristina"
Дата:
Hello again, Marcel.
 
I tried this and it seems to work on the example you provided, iif my understanding is correct and you want the ID=2 to have just one record on final output.
That makes sense to me because

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

 
(SELECT x."ID",x."BEG",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 ((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")))
 
WHERE yid IS NOT NULL
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 -----
Sent: Wednesday, June 15, 2011 4:23 PM
Subject: [SQL] Merge overlapping time-periods

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