SELECT *
FROM (
SELECT username
FROM friends
START WITH
username = 'myname'
CONNECT BY
friendname = PRIOR username
AND level <= 3
)
WHERE username = 'friendname'
AND rownum = 1
Cập nhật cấp độ nếu cần:bạn có thể tìm kiếm bạn bè ở lớp thứ ba, v.v.
Nếu mối quan hệ bạn bè là đối xứng, bạn nên thực hiện truy vấn sau:
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
Truy vấn này có thể được thực hiện nhanh hơn nhiều nếu bạn không chuẩn hóa bảng của mình:lưu trữ hai bản ghi cho mỗi tình bạn, như sau:
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
Sau đó, bạn chỉ có thể thay thế CTE
ở trên với 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
, sẽ sử dụng chỉ mục và hiệu quả hơn nhiều, đặc biệt nếu bạn giới hạn mức ở một số giá trị hợp lý.