Oracle SQL how to write a sql statement that verifies if user in my network( ie friends or friend of friends)

前端 未结 2 579
醉话见心
醉话见心 2021-01-18 01:23

I have this problem. Given a users table that consists of users\' username in a social network and friends table that contain a user\'s name and a

相关标签:
2条回答
  • 2021-01-18 01:51
    SELECT  *
    FROM    (
            SELECT  username
            FROM    friends
            START WITH
                    username = 'myname'
            CONNECT BY
                    friendname = PRIOR username
                    AND level <= 3
            )
    WHERE   username = 'friendname'
            AND rownum = 1
    

    Update the level as necessary: you may search for the third layer friends etc.

    If the friendship relationship is symmetric, you should make the following query:

    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
    

    This query can be made much faster if you denormalize your table: store two records per friendship, like this:

    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
    

    Then you can just replace the CTE above with the 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
    

    , which will use the index and be much more efficient, especially if you limit the level to some reasonable value.

    0 讨论(0)
  • 2021-01-18 02:13

    You can use connect by

    0 讨论(0)
提交回复
热议问题