Oracle
 sql >> Datenbank >  >> RDS >> Oracle

Oracle SQL, wie man eine SQL-Anweisung schreibt, die überprüft, ob Benutzer in meinem Netzwerk sind (dh Freunde oder Freunde von Freunden)

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.