Puede hacer esto usando consultas jerárquicas:aquí hay una que usa el estilo antiguo 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
El prior sys_guid() is not null
La condición en la cláusula connect by es necesaria para garantizar que estamos recorriendo las filas correctas (si tuviera que omitirla, el resultado contendría muchas filas adicionales).
He excluido filas con un solo estado en la salida, excepto si la identificación solo enumera un solo estado. Es posible que desee o no incluir estados individuales en la salida, en cuyo caso, puede eliminar los predicados por completo.