Het is onduidelijk of de relaties reflexief zijn (d.w.z. als B
is een "broer of zus" van A
dan A
is een "broer of zus" van B
) omdat u enkele dubbele rijen heeft met de omgekeerde relaties in uw gegevens en sommige waar deze eigenschap niet duidelijk is.
Ervan uitgaande dat uw relaties niet reflexief zijn, dan:
Oracle 11g R2 Schema-instellingen :
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;
Query 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
| 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 |
Vraag 2 :Als ze reflexief zijn, kun je UNION [ALL]
. gebruiken om de tabel te dupliceren met de relaties in de omgekeerde richting en dan de vorige techniek te gebruiken:
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
| 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 |