2015-05-28 2 views
5

Eingabe ist ein Array von 'n' Länge. Ich muss alle möglichen Kombinationen von Array-Elementen generieren, einschließlich aller Kombinationen mit weniger Elementen aus dem Eingabe-Array.PostgreSQL findet alle möglichen Kombinationen (Permutationen) in der rekursiven Abfrage

IN: j='{A, B, C ..}' 
OUT: k='{A, AB, AC, ABC, ACB, B, BA, BC, BAC, BCA..}' 

Mit Wiederholungen, so mit ABBA ..

ich so etwas wie dies versucht haben:

WITH RECURSIVE t(i) AS (SELECT * FROM unnest('{A,B,C}'::text[])) 
,cte AS (
    SELECT i AS combo, i, 1 AS ct 
    FROM t 
    UNION ALL 
    SELECT cte.combo || t.i, t.i, ct + 1 
    FROM cte 
    JOIN t ON t.i > cte.i 
) 
SELECT ARRAY(SELECT combo FROM cte ORDER BY ct, combo) AS result; 

Es wird Kombinationen ohne Wiederholungen zu erzeugen ... also muss ich das irgendwie ändern .

+4

Was haben Sie versucht? Müssen Sie das in Postgres tun? Können Sie pl/PGSQL oder eine andere prozedurale Sprache verwenden? Müssen Sie Arrays verwenden? –

+0

wollen Sie nur Strings der Länge 1 bis 3? – 1010

+0

Eingabe soll Variable sein, also sollte es Kombinationen von allen Elementen im Array machen. – Adam

Antwort

2

Bei einer rekursiven Abfrage werden die Begriffe in der Suchtabelle entfernt, die in einer Iteration verwendet werden, und dann wird die Abfrage mit den verbleibenden Datensätzen wiederholt. In Ihrem Fall bedeutet dies, dass sobald Sie das erste Array-Element ("A") bearbeitet haben, es für weitere Permutationen der Array-Elemente nicht mehr verfügbar ist. Um diese "verwendeten" Elemente wieder einzufügen, müssen Sie die Tabelle der Array-Elemente in der rekursiven Abfrage kreuzen und dann die bereits in der aktuellen Permutation verwendeten Array-Elemente (position(t.i in cte.combo) = 0) und eine Bedingung zum Stoppen der Iterationen (ct <= 3) herausfiltern).

+0

Hier ist eine SQL Fiddle: http://www.sqlfiddle.com/#!15/9eecb7db59d16c80417c72d1e1f4fbf1/ 497. –

+0

@Patrick Danke Mann! Du hast gerade meinen Tag gemacht .. :) Lebensretter .. danke .. – Adam