如何创建验证朋友的朋友的SQL查询

时间:2009-09-20 19:59:04

标签: sql database

我有两张桌子。

USER user_id密码

FRIEND_LIST user_id friend_id

如果用户1是用户2的朋友,那么在friend_list中将有2条记录:

1 2
2 1

这就是我如何控制好友列表。

我的问题是如何创建一个有效的查询来验证用户是否是朋友的朋友。

例如,用户1在他的朋友列表中具有用户2.并且用户3在他的朋友列表中具有用户2.因此用户2是1和3的共同朋友。

以下是friend_list表的外观:

1 2
2 1
3 2
2 3

不,我想知道用户1是否有朋友作为朋友用户3。

伪代码如下:

validate(){    
valid = false
    list = get all friends from user 1 and store them in 'list'.
    for each friend in list {
       list2 = get all friends from friend
       for each friend2 in list2 {
        if friend2.user_id = 3 }
          valid = true
          break; //stop here because we have found that 3 is a friend of a friend of 1
        }
     }
    }
return valid
}

这就是编程语言的样子。现在我想验证相同但仅使用SQL查询。

我试过了,但我不知道这是否是一种验证它的好方法。

select *
from friend_list fl1
inner join friend_list fl2 on fl1.user_id = fl2.user_id
inner join friend_list fl3 on fl2.friend_id = fl3.user_id
where fl1.user_id = 1 and fl3.friend_id = 3

提前致谢。

非常感谢您的支持。这是我第一次使用这个论坛 并帮助了我很多。

我使用了您发布的EXISTS代码。

SELECT EXISTS (
    SELECT
        *
    FROM
        friend_list AS users
    INNER JOIN
        friend_list AS friends
            ON users.friend_id = friends.user_id
    WHERE
        users.user_id = 1
        AND friends.friend_id = 3
) AS result

2 个答案:

答案 0 :(得分:1)

您已经编写的查询是沿着正确的行,我认为您需要少一次加入到朋友列表中:

select distinct fl1.user_id, fl2.friend_id
from friend_list fl1
inner join friend_list fl2 on fl1.friend_id = fl2.user_id
where fl1.user_id = 1 and fl2.friend_id = 3

所以'1'(fl1.user_id)是'x'(fl1.friend_id和fl2.user_id)的朋友,他们是'3'(fl2.friend_id)的朋友。

因为在每对朋友的朋友列表中有两个互补条目,所以查询很简单。如果每对朋友只在朋友列表中排成一行,那就更难了......

(编辑:实现了太多的联接......) (编辑:在评论对话后添加一个独特的选择)

答案 1 :(得分:1)

当你想知道是否存在“a和b有一个共同的朋友”的任何实例时,你最好使用EXISTS关键字。

这比使用COUNT或DISTINT更有利于优化者知道一些事情:
1.实际数据无关紧要 2.它可以在第一次点击后停止搜索

例如......

IF EXISTS (
    SELECT
        *
    FROM
        friend_list AS [user]
    INNER JOIN
        friend_list AS [friend]
            ON [user].friend_id = [friend].user_id
    WHERE
        [user].user_id = @user_id
        AND [friend].friend_id = @friend_of_friend_id
)
BEGIN
    RETURN 1
    -- Or whatever code you want to execute
END
ELSE
BEGIN
    RETURN 0
    -- Or whatever code you want to execute
END

虽然它没有“TOP 1”并且使用“*”,但它实际上既不返回多个字段或行。它实际上只是搜索匹配的存在,并在找到匹配时停止。