Không rõ liệu các mối quan hệ có phải là phản xạ hay không (tức là nếu B
là "anh chị em" của A
rồi đến A
là "anh chị em" của B
) vì bạn có một số hàng trùng lặp với các mối quan hệ đảo ngược trong dữ liệu của mình và một số hàng trong đó thuộc tính này không rõ ràng.
Giả sử rằng các mối quan hệ của bạn không phải là phản xạ thì:
Thiết lập lược đồ Oracle 11g R2 :
CREATE TABLE A ( ID, SIBS ) AS
SELECT 'A', 'B' FROM DUAL UNION ALL
SELECT 'A', 'C' FROM DUAL UNION ALL
SELECT 'B', 'A' FROM DUAL UNION ALL
SELECT 'C', 'A' FROM DUAL UNION ALL
SELECT 'C', 'D' FROM DUAL UNION ALL
SELECT 'D', 'C' FROM DUAL UNION ALL
SELECT 'E', 'F' FROM DUAL UNION ALL
SELECT 'F', 'G' FROM DUAL UNION ALL
SELECT 'G', 'H' FROM DUAL;
Truy vấn 1 :
SELECT DISTINCT
CONNECT_BY_ROOT( ID ) AS ID,
SIBS
FROM A
WHERE CONNECT_BY_ROOT( ID ) <> SIBS
CONNECT BY NOCYCLE
PRIOR SIBS = ID
ORDER BY ID, SIBS
Kết quả :
| ID | SIBS |
|----|------|
| A | B |
| A | C |
| A | D |
| B | A |
| B | C |
| B | D |
| C | A |
| C | B |
| C | D |
| D | A |
| D | B |
| D | C |
| E | F |
| E | G |
| E | H |
| F | G |
| F | H |
| G | H |
Truy vấn 2 :Nếu chúng phản xạ thì bạn có thể sử dụng UNION [ALL]
để sao chép bảng với các mối quan hệ theo hướng ngược lại và sau đó sử dụng kỹ thuật trước đó:
SELECT DISTINCT
CONNECT_BY_ROOT( ID ) AS ID,
SIBS
FROM (
SELECT ID, SIBS FROM A
UNION
SELECT SIBS, ID FROM A
)
WHERE CONNECT_BY_ROOT( ID ) <> SIBS
CONNECT BY NOCYCLE
PRIOR SIBS = ID
ORDER BY ID, SIBS
Kết quả :
| ID | SIBS |
|----|------|
| A | B |
| A | C |
| A | D |
| B | A |
| B | C |
| B | D |
| C | A |
| C | B |
| C | D |
| D | A |
| D | B |
| D | C |
| E | F |
| E | G |
| E | H |
| F | E |
| F | G |
| F | H |
| G | E |
| G | F |
| G | H |
| H | E |
| H | F |
| H | G |