2015-05-28 13 views
5

Wejście to tablica o długości 'n'. Muszę wygenerować wszystkie możliwe kombinacje elementów tablicy, w tym wszystkie kombinacje z mniejszą liczbą elementów z tablicy wejściowej.PostgreSQL znajduje wszystkie możliwe kombinacje (permutacje) w zapytaniu cyklicznym

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

Z powtórek, więc z ABBA ..

Próbowałem coś takiego:

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; 

To jest generowanie kombinacji bez powtórzeń ... więc muszę modyfikować że jakoś .

+4

Co próbowaliście? Czy musisz to zrobić w Postgres? Czy możesz użyć języka pl/PGSQL lub innego języka proceduralnego? Musisz użyć tablic? –

+0

Czy chcesz mieć ciągi o długości od 1 do 3? – 1010

+0

Dane wejściowe mają być zmienne, więc powinny tworzyć kombinacje ze wszystkich elementów w tablicy .. – Adam

Odpowiedz

2

W zapytaniu rekursywnym terminy w tabeli wyszukiwania, które są używane w iteracji, są usuwane, a następnie zapytanie powtarza się z pozostałymi rekordami. W twoim przypadku oznacza to, że jak tylko przetworzysz pierwszy element tablicy ("A"), nie będzie on już dostępny dla dalszych permutacji elementów tablicy. Aby odzyskać te "używane" elementy, należy połączyć krzyżowo z tabelą elementów tablicy w kwerendzie rekurencyjnej, a następnie odfiltrować elementy tablicy już używane w bieżącej permutacji (position(t.i in cte.combo) = 0) i warunek zatrzymania iteracji (ct <= 3).

WITH RECURSIVE t(i) AS (
    SELECT * FROM unnest('{A,B,C}'::char[]) 
), 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, t 
    WHERE ct <= 3 
     AND position(t.i in cte.combo) = 0 
) 
SELECT ARRAY(SELECT combo FROM cte ORDER BY ct, combo) AS result; 
+0

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

+0

@Patrick Dziękuję człowieku! Właśnie zrobiłeś mój dzień .. :) ratownik .. dziękuję .. – Adam

Powiązane problemy