SELECT *
FROM (
SELECT username
FROM friends
START WITH
username = 'myname'
CONNECT BY
friendname = PRIOR username
AND level <= 3
)
WHERE username = 'friendname'
AND rownum = 1
Aktualisieren Sie die Ebene nach Bedarf:Sie können nach Freunden der dritten Ebene usw. suchen.
Wenn die Freundschaftsbeziehung symmetrisch ist, sollten Sie die folgende Abfrage durchführen:
WITH q AS
(
SELECT username, friendname
FROM friends
UNION ALL
SELECT friendname, username
FROM friends
),
f AS
(
SELECT friendname, level
FROM q
START WITH
username = 'Thomas'
CONNECT BY NOCYCLE
username = PRIOR friendname
)
SELECT *
FROM f
WHERE friendname = 'Jo'
AND rownum = 1
Diese Abfrage kann viel schneller durchgeführt werden, wenn Sie Ihre Tabelle denormalisieren:Speichern Sie zwei Datensätze pro Freundschaft, wie folgt:
CREATE TABLE dual_friends (orestes NOT NULL, pylades NOT NULL, CONSTRAINT pk_dualfriends_op PRIMARY KEY (orestes, pylades)) ORGANIZATION INDEX
AS
SELECT username, friendname
FROM friends
UNION ALL
SELECT friendname, username
FROM friends
Dann können Sie einfach den CTE
ersetzen oben mit den dual_friends
:
WITH f AS
(
SELECT pylades, level
FROM dual_friends
START WITH
orestes = 'Thomas'
CONNECT BY NOCYCLE
orestes = PRIOR pylades
AND level <= 3
)
SELECT *
FROM f
WHERE pylades = 'Jo'
AND rownum = 1
, die den Index verwendet und viel effizienter ist, insbesondere wenn Sie die Ebene auf einen vernünftigen Wert begrenzen.