2016-10-05 4 views
1

Ich habe eine Tabelle, wo jeder Datensatz einen Indikator und einen Bereich hat, und ich möchte die Gesamtspreizung durch die Bereiche für jeden Indikator - aber nicht doppelt zählen, wenn Bereiche sich überlappen ein bestimmter Indikator.Berechnen Sie die Gesamtspreizung durch mehrere Bereiche

Ich kann sehen, dass die Formulierung ist schwer zu folgen, aber das Konzept ist ziemlich einfach. Lassen Sie mich ein anschauliches Beispiel geben.

CREATE TABLE records(id int, spread int4range); 
INSERT INTO records VALUES 
    (1, int4range(1, 4)), 
    (1, int4range(2, 7)), 
    (1, int4range(11, 15)), 
    (2, int4range(3, 5)), 
    (2, int4range(6, 10)); 
SELECT * FROM records; 

Nachgeben die Ausgabe:

id | spread 
----+--------- 
    1 | [1,4) 
    1 | [2,7) 
    1 | [11,15) 
    2 | [3,5) 
    2 | [6,10) 
(5 rows) 

Ich würde jetzt wie eine Abfrage, die die folgende Ausgabe gibt:

id | total 
---+-------- 
1 | 10 
2 | 6 

Wo sind die Zahlen 10 und 6 kommen aus? Für ID 1 haben wir Bereiche, die 1, 2, 3, 4, 5, 6, 11, 12, 13 und 14 enthalten; insgesamt 10 verschiedene ganze Zahlen. Für ID 2 haben wir Bereiche, die 3, 4, 6, 7, 8 und 9 enthalten; insgesamt sechs verschiedene ganze Zahlen.

Wenn es Ihnen hilft, das Problem zu verstehen, können Sie es sich vorstellen: "Wenn diese Aufzeichnungen den Tag und die Zeit für Besprechungen in meinem Kalender darstellen, wie viele Stunden pro Tag gibt es dort, wo ich gebucht habe? wenigstens einmal?"

Postgres-Version ist 9.4.8, falls das wichtig ist.

Antwort

3
select id, count(*) 
from (
    select distinct id, generate_series(lower(spread), upper(spread) - 1) 
    from records 
) s 
group by id 
; 
id | count 
----+------- 
    1 | 10 
    2 |  6 
+0

Haha, die Antwort erweist sich als so einfach. Es ist komisch, wie dein Verstand hängen bleibt - ich war wirklich auf einen viel komplizierteren Prozess fixiert, wo ich zuerst die Vereinigung nehme (unzusammenhängende Bereiche handhabe) und dann die Grenzen davon betrachte. Vielen dank für Deine Hilfe. –

Verwandte Themen