2016-12-27 15 views
1

Ich habe zwei Spalten wie folgt:Wie findet man Überlappungen zwischen zwei Integer-Reihen in PostgreSQL?

start end  id 
120  125 1 
1  13  2 
14  17  3 
100  121 4 
99  100 5 
2   6  6 

Wie Sie id=4 and id=5, eine Überlappung zwischen gibt es sehen können id=1 and id=4, beachten Sie id=6 and id=2

ich sollte, dass start immer kleiner oder gleich zu end.

Wie kann ich diese Überlappungen mit SQL finden? Grundsätzlich möchte ich das Ergebnis sein:

1 
2 
4 
5 
6 

Antwort

1

Sie würden jede ID erhalten, die mit einem anderen überlappt exists mit:

select id 
from t 
where exists (select 1 
       from t t2 
       where t2.start <= t.end and t2.end >= t.start and t2.id <> t.id 
      ); 

ich denke, es wäre sinnvoll, die Paare von ids zu sehen daß Überlappung:

select t.id, t2.id 
from t t join 
    t t2 
    on t2.start <= t.end and t2.end >= t.start and t.id < t2.id; 

EDIT:

Hier ist eine Demonstration davon arbeiten:

with t (start, "end", id) as (
    values (120, 125, 1), 
      (1, 13, 2), 
      (14, 17, 3), 
      (100, 121, 4), 
      (99, 100, 5), 
      (2, 6, 6) 
    ) 
select id 
from t 
where exists (select 1 
       from t t2 
       where t2.start <= t."end" and t2."end" >= t.start and t.id <> t2.id 
      ); 
+0

Es hat einen großen Fehler ... es nur von ID zu höheren ids prüft .... was bedeutet, dass, wenn ich hinzufügen, in dem die Bedingung zu einer bestimmten ID Beispiel t.id = 4 ... es wird nicht zum Beispiel mit id = 2 verglichen. – avi

+0

Die 'exists'-Lösung ist nicht korrekt, sie gibt auch' id = 3 'aus, die keine andere Serie überlappt. – MtwStark

0
select distinct d1.id 
    --, d2.id id_overlap -- if you want to see the overlapping serie id uncomment this line 
from t d1 
join t d2 on 
    (d1.id <> d2.id) and 
    ( 
    (d1.start between d2.start and d2.[end] or d1.[end] between d2.start and d2.[end]) 
    or 
    (d2.start between d1.start and d1.[end] or d2.[end] between d1.start and d1.[end]) 
    ) 
Verwandte Themen