2015-05-28 16 views
5

L'input è una matrice di lunghezza 'n'. Devo generare tutte le possibili combinazioni di elementi dell'array, incluse tutte le combinazioni con meno elementi dall'array di input.PostgreSQL trova tutte le combinazioni possibili (permutazioni) nella query ricorsiva

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

Con ripetizioni, quindi con ABBA ..

Ho provato qualcosa di simile:

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; 

Si sta generando combinazioni senza ripetizioni ... quindi ho bisogno di modificare che in qualche modo .

+4

Cosa hai provato? Devi farlo a Postgres? Puoi usare pl/PGSQL o un altro linguaggio procedurale? Devi usare gli array? –

+0

vuoi stringhe di lunghezza solo da 1 a 3? – 1010

+0

L'input deve essere variabile, quindi dovrebbe creare combinazioni da tutti gli elementi dell'array. – Adam

risposta

2

In una query ricorsiva i termini nella tabella di ricerca utilizzati in un'iterazione vengono rimossi e quindi la query viene ripetuta con i record rimanenti. Nel tuo caso ciò significa che non appena è stato elaborato il primo elemento dell'array ("A") non è più disponibile per ulteriori permutazioni degli elementi dell'array. Per ripristinare gli elementi "usati", è necessario eseguire l'unione incrociata con la tabella degli elementi dell'array nella query ricorsiva e quindi filtrare gli elementi dell'array già utilizzati nella permutazione corrente (position(t.i in cte.combo) = 0) e una condizione per arrestare le iterazioni (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

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

+0

@Patrick Grazie amico! Hai appena fatto la mia giornata .. :) salvagente .. grazie .. – Adam

Problemi correlati