Oracle
 sql >> Base de Dados >  >> RDS >> Oracle

Combinações de uma única tabela, agrupadas por um valor de coluna


Você pode fazer isso usando consultas hierárquicas - aqui está uma usando o estilo antigo connect by :
WITH your_table AS (SELECT 1 ID, 'AL' state FROM dual UNION ALL
                    SELECT 1 ID, 'AZ' state FROM dual UNION ALL
                    SELECT 1 ID, 'MI' state FROM dual UNION ALL
                    SELECT 2 ID, 'TX' state FROM dual UNION ALL
                    SELECT 2 ID, 'TN' state FROM dual UNION ALL
                    SELECT 2 ID, 'MO' state FROM dual UNION ALL
                    SELECT 2 ID, 'ND' state FROM dual UNION ALL
                    SELECT 3 ID, 'OH' state FROM dual)
SELECT ID,
       state,
       ltrim(SYS_CONNECT_BY_PATH(state, ','), ',') combinations,
       LEVEL
FROM   (SELECT id,
               state,
               count(*) OVER (PARTITION BY id) state_cnt
        FROM your_table)
WHERE  state_cnt = 1
OR     (state_cnt > 1 AND LEVEL > 1)
CONNECT BY PRIOR ID = ID
           AND PRIOR state < state
           AND PRIOR sys_guid() IS NOT NULL;

        ID STATE COMBINATIONS      LEVEL
---------- ----- ------------ ----------
         1 AZ    AL,AZ                 2
         1 MI    AL,AZ,MI              3
         1 MI    AL,MI                 2
         1 MI    AZ,MI                 2
         2 TX    TN,TX                 2
         2 TX    MO,TX                 2
         2 TN    MO,TN                 2
         2 TX    MO,TN,TX              3
         2 ND    MO,ND                 2
         2 TX    MO,ND,TX              3
         2 TN    MO,ND,TN              3
         2 TX    MO,ND,TN,TX           4
         2 TX    ND,TX                 2
         2 TN    ND,TN                 2
         2 TX    ND,TN,TX              3
         3 OH    OH                    1

O prior sys_guid() is not null A condição na cláusula connect by é necessária para garantir que estamos fazendo um loop nas linhas corretas (se você a omitir, o resultado conterá muitas linhas extras).

Excluí linhas com apenas um único estado na saída - exceto se o id listar apenas um único estado. Você pode ou não querer incluir estados únicos na saída; nesse caso, você pode remover os predicados completamente.