Não está claro se os relacionamentos são reflexivos (ou seja, se
B
é um "irmão" de A
então A
é um "irmão" de B
), pois você tem algumas linhas duplicadas com os relacionamentos invertidos em seus dados e algumas em que essa propriedade não é evidente. Assumindo que seus relacionamentos não são reflexivos, então:
SQL Fiddle
Configuração do esquema 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;
Consulta 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
Resultados :
| 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 |
Consulta 2 :Se eles são reflexivos, você pode usar
UNION [ALL]
para duplicar a tabela com os relacionamentos na direção inversa e depois usar a técnica anterior: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
Resultados :
| 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 |