Можете да направите това, като използвате йерархични заявки - ето една, използваща стария стил 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
prior sys_guid() is not null
условието в клаузата за свързване чрез е необходимо, за да сме сигурни, че преминаваме през правилните редове (ако го пропуснете, резултатът ще съдържа много допълнителни редове).
Изключих редове само с едно състояние в изхода - освен ако идентификаторът посочи само едно състояние. Можете или не можете да искате да включите отделни състояния в изхода, в който случай можете да премахнете изцяло предикатите.