Ist es möglich, in Postgres eine Art Gruppierungskette zu erstellen? Angenommen, ich habe die folgende Tabelle:
CREATE TABLE foo AS
SELECT row_number() OVER () AS id, *
FROM ( VALUES
( 'X', 'D', 'G', 'P' ),
( 'F', 'D', 'L', 'M' ),
( 'X', 'N', 'R', 'S' ),
( 'Y', 'I', 'W', NULL ),
( 'U', 'Z', 'E', NULL )
) AS f(a,b,c,d);
id | a | b | c | d
------------------
1 | X | D | G | P
2 | F | D | L | M
3 | X | N | R | S
4 | Y | I | W |
5 | U | Z | E |
Ich möchte irgendwie eine herstellen GROUP BY, die drei Gruppen ergibt:
1,2Und3zusammen1und2wegen einer gemeinsamenDin derbSpalte1und3wegen einer gemeinsamenXin deraSpalte
4allein (keine gemeinsamen Werte in einer der Spalten; Nullen sollten nicht übereinstimmen)5allein (keine gemeinsamen Werte in einer der Spalten; Nullen sollten nicht übereinstimmen)
Ich verwende derzeit Postgres 9.5, aber wir werden irgendwann auf 9.6 aktualisieren. Wenn also etwas drin ist, das mir hilft, bin ich offen dafür, es zu hören.
Mit anderen Worten, ich suche nach etwas wie (sagen wir, ich habe array_agg(DISTINCT a)usw. verwendet , um die Anzeige einfacher zu halten):
ids | as | bs | cs | ds
-----------------------------------------------------------------------
{1, 2, 3} | {'X', 'F'} | {'D', 'N'} | {'G', 'L', 'R'} | {'P', 'M', 'S'}
{4} | {'Y'} | {'I'} | {'W'} | {NULL}
{5} | {'U'} | {'Z'} | {'E'} | {NULL}
(Ich bin mir nicht ganz sicher, wie die Nullen angezeigt werden sollen. Lassen Sie sich also nicht zu sehr darauf ein. Der wichtige Punkt ist, dass sie nicht zueinander passen sollten.)
Wenn ich benutze GROUP BY CUBE (a, b, c, d), bekomme ich weit mehr als drei Ergebnisse ... dito GROUP BY ROLLUPund GROUP BY GROUPING SETS.
Gibt es einen eleganten Weg in Postgres? Ich kann mir vorstellen, wie Sie es in Ruby über Active Record machen würden (durchlaufen Sie jeden Datensatz, gruppieren Sie ihn mit vorherigen gruppierten Sätzen, die übereinstimmen), aber ich würde dies gerne in Postgres behalten, wenn dies möglich ist.