2016-06-17 5 views
0

Ich habe Daten in einem PostegreSQL Tabelle, die wie folgt aussieht:Gruppe und Aggregate Strings basierend auf Bestellung und Schlüsselfelder

text      field1 field2 ID 
Lorem ipsum dolor    A  B  1 
Donec tristique ips   A  C  2 
Donec ut imperdiet neque,  A  B  3 
Suspendisse urna nunc,  A  B  4 
tristique auctor libero.  A  C  5 
sem varius nec    A  C  6 

ich eine Art zweite ID hinzufügen möchten, die Gruppen den Text von field1 und field2 während Behalten Sie die Reihenfolge des Tisches bei. So etwas wie dieses:

text      field1 field2 ID ID2 
Lorem ipsum dolor    A  B  1  1 
Donec tristique ips   B  C  2  2 
Donec ut imperdiet neque,  A  B  3  3 
Suspendisse urna nunc,  A  B  4  3 
tristique      B  C  5  4 
sem varius nec    B  C  6  4 
sem neque auctor    B  C  7  4 

Ich würde dann gruppieren und aggregieren mein Textfeld basierend auf diesem ID2-Feld. Das Endergebnis würde wie folgt aussehen:

text             field1 field2 ID2 
Lorem ipsum dolor          A   B   1 
Donec tristique ips         B   C   2 
Donec ut imperdiet neque, Suspendisse urna nunc,  A   B   3  
tristique sem varius necsem neque auctor    B   C   4 

Welche Abfrage würde ich laufen, um brauchen dieses Ergebnis zu bekommen?

Danke,

+0

'string_agg (... order by ...)' –

+5

Was meinen Sie mit "Reihenfolge der Tabelle"? Tabellen haben ** keine ** Reihenfolge. Ohne eine 'ORDER BY'-Klausel in Ihrem' SELECT', kann der Server die Ergebnisse in beliebiger Reihenfolge zurückgeben. Wenn Sie im ORDER BY keine Spalte (n) angeben müssen, liegt ein Problem mit Ihrem Datenmodell vor. –

+0

In der Reihenfolge meine ich verketten mein Textfeld wenn Feld1 und Feld2 und die gleiche wie die vorherige Zeile wie mein Beispiel oben. – nickfrenchy

Antwort

0

Sie können eine „interne“ Bestellung zu jedem Aggregatfunktion geben:

SELECT array_agg(text ORDER BY id) AS text, 
     field1, field2, 
     row_number() OVER() AS id2 
FROM t 
GROUP BY field1, field2 
ORDER BY id2 

Wenn Sie das Ergebnis drucken oder es in eine Anwendung ziehen, können Sie es vorziehen string_agg zu verwenden anstelle von array_agg, mit einem , für das Trennzeichen.

EDIT: Hier ist eine Abfrage, die „läuft“ identischer field1 + field2 Werte, wenn Zeilen geordnet nach id identifiziert:

SELECT array_agg(text ORDER BY id), 
     field1, field2, 
     row_number() OVER() 
FROM (
     SELECT t.*, 
       (SELECT MIN(t2.id) 
       FROM t t2 
       WHERE t2.id <= t.id 
       AND t2.field1 = t.field1 
       AND t2.field2 = t.field2 
       AND NOT EXISTS (SELECT 1 
            FROM t t3 
            WHERE t3.id < t.id 
            AND  t3.id > t2.id 
            AND  (t3.field1 <> t.field1 
            OR  t3.field2 <> t.field2))) AS g 
     FROM t 
     ) AS x 
GROUP BY g, field1, field2 
ORDER BY g 
; 

Ich halte diese Abfrage etwas lächerlich, und ich weiß nicht verbürgen für seine Leistung, aber es tut, was Sie verlangen. Auch da Sie nicht bereit sind, zahlreiche Leute zu akzeptieren, die erklären, dass ein Tisch keine natürliche Ordnung hat, sollten Sie wirklich ein gutes Buch über das relationale Modell finden und es lesen.

+0

Wie erhalten Sie ID2? – nickfrenchy

+0

Ha ha, du bist derjenige, der es erwähnt hat! Also willst du es generieren? –

+0

Ja, es war mein fehlender Schritt: P Ok, ich habe dein Skript ausprobiert und es funktioniert, aber es ist nicht genau das, was ich suche. Dies verkettet alle A B, B C zusammen unabhängig von ihrer Position. Was ich suche ist: Stellen Sie sich vor, Sie haben Dialoge und ein Dialog ist über mehrere Zeilen verteilt, ich möchte eine Zeile pro Dialog haben. – nickfrenchy