Bạn có thể thực hiện việc này bằng cách sử dụng các truy vấn phân cấp - đây là một truy vấn sử dụng kiểu cũ 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
điều kiện trong mệnh đề connect by là bắt buộc để đảm bảo chúng ta đang lặp qua các hàng chính xác (nếu bạn bỏ qua nó, kết quả sẽ chứa nhiều hàng thừa).
Tôi đã loại trừ các hàng chỉ có một trạng thái duy nhất trong đầu ra - ngoại trừ nếu id chỉ liệt kê một trạng thái duy nhất. Bạn có thể muốn hoặc không muốn bao gồm các trạng thái đơn lẻ trong đầu ra, trong trường hợp đó, bạn có thể loại bỏ hoàn toàn các vị từ.