2015-09-02 9 views
8
CREATE TABLE entries (
    id serial NOT NULL, 
    title character varying, 
    load_sequence integer 
); 

und DatenWie GROUP Einträge durch ununterbrochene Reihenfolge?

INSERT INTO entries(title, load_sequence) VALUES ('A', 1); 
INSERT INTO entries(title, load_sequence) VALUES ('A', 2); 
INSERT INTO entries(title, load_sequence) VALUES ('A', 3); 

INSERT INTO entries(title, load_sequence) VALUES ('A', 6); 

INSERT INTO entries(title, load_sequence) VALUES ('B', 4); 
INSERT INTO entries(title, load_sequence) VALUES ('B', 5); 

INSERT INTO entries(title, load_sequence) VALUES ('B', 7); 
INSERT INTO entries(title, load_sequence) VALUES ('B', 8); 

Gibt es eine Möglichkeit in PostgreSQL SQL, dass Gruppen von Daten gleichen title Segmente zu schreiben, nachdem sie durch load_sequence bestellen. ich meine:

=# SELECT id, title, load_sequence FROM entries ORDER BY load_sequence; 
id | title | load_sequence 
----+-------+--------------- 
    9 | A  |    1 
10 | A  |    2 
11 | A  |    3 
13 | B  |    4 
14 | B  |    5 
12 | A  |    6 
15 | B  |    7 
16 | B  |    8 

und ich möchte Gruppen:

=# SELECT title, string_agg(id::text, ',' ORDER BY id) FROM entries ???????????; 

so würde zur Folge haben:

title | string_agg 
-------+------------- 
A  | 9,10,11 
B  | 13,14 
A  | 12 
B  | 15,16 
+1

Leider sind solche Fragen selten, die Tabellenerstellungsskripts und runnable INSERT-Anweisungen enthalten, die die Beispieldaten einrichten. +1 von mir. –

Antwort

4

Sie die folgende Abfrage verwenden:

SELECT title, string_agg(id::text, ',' ORDER BY id) 
FROM (
    SELECT id, title, 
     ROW_NUMBER() OVER (ORDER BY load_sequence) - 
     ROW_NUMBER() OVER (PARTITION BY title 
          ORDER BY load_sequence) AS grp 
    FROM entries) AS t 
GROUP BY title, grp 

BerechnetDas Felddient zum Identifizieren von Schnitten von title Datensätzen mit fortlaufenden load_sequence Werten. Unter Verwendung dieses Felds in der GROUP BY-Klausel können wir die erforderliche Aggregation über id Werte erreichen.

Demo here

+0

Danke, ich habe die Idee. Mit kleinen Modifikationen für meinen speziellen Fall funktioniert es endlich. – oskarae

0

Es gibt einen Trick, den Sie mit sum als Fensterfunktion läuft über einen lag ged Fenster für diese verwenden können.

Die Idee ist, dass, wenn Sie eine Kante/Diskontinuität treffen, Sie 1 zurückgeben, andernfalls geben Sie 0 zurück. Sie erkennen die Diskontinuitäten mit der lag Fensterfunktion.