“朋友提要”的尴尬SQL查询

时间:2009-08-24 15:58:19

标签: sql join

我正在尝试将社交网络元素编码到我们的网站。我们有两个表,一个显示用户,一个显示这些用户之间的友谊。

Users:
 userid - PK, int
 name
 profilepic

Friendships:
 id - PK int
 userid
 friendid
 datecreated

友谊表是双向的 - 即有人可以在没有他们的情况下与他人交朋友

我需要一个查询来获取用户的所有朋友,他们的朋友已经建立的新友谊,以及新友情的名字和profilepic。

噩梦!所有人都非常感谢!

5 个答案:

答案 0 :(得分:1)

-- all friends for a user
select f.*
from Users u
inner join Friendships f
on u.userid = f.userid
where u.userid = 1

-- new friends of friends
select ffu.*
from Users u
inner join Friendships f
on u.userid = f.userid
inner join Friendships ff
on f.friendid = ff.userid
inner join Users ffu
on ff.userid = ffu.userid
where u.userid = 1
and ff.datecreated > getdate() -30

答案 1 :(得分:1)

是的,你在这里有两个不同的查询,一个是朋友信息,另一个是新朋友信息。尝试一起做这些事并没有真正的意义。

  

用户的所有朋友

SELECT friends.userid, friends.name, friends.profilepic
FROM friendships
JOIN users AS friends ON friends.userid=friendships.friendid
WHERE friendships.userid=[user's id]
  

他们的朋友们已经建立了新的友谊

好的,这是朋友之间的朋友关系,你可以通过友谊表两次找到它。这称为自联接:

SELECT friendoffriends.userid, friendoffriends.name, friendoffriends.profilepic
FROM friendships AS ships1
JOIN friendships AS ships2 ON ships2.userid=ships1.friendid
JOIN users AS friendoffriends ON friends.userid=ships2.friendid
WHERE ships1.userid=[user's id]
AND ships2.datecreated>=[last visit time]

答案 2 :(得分:0)

这不应该在纯SQL中完成。虽然您现在可以轻松定义您的关系,但您可能(将?)想要将内容添加到“Feed”上的项目列表中。这个更适合在消费代码中聚合的东西。

答案 3 :(得分:0)

试试这个(sql server):

declare @users table (userid int primary key identity(1,1), name varchar(10), profilepic char(1))
declare @friendships table (id int primary key identity(1,1), userid int, friendid int, datecreated datetime)

insert into @users values ('bill','b')
insert into @users values ('matt','m')
insert into @users values ('steve','s')
insert into @users values ('fred','f')
insert into @users values ('joe','j')

insert into @friendships values (1,2,'8/24/2008')
insert into @friendships values (1,3,'8/24/2008')
insert into @friendships values (2,1,'8/24/2008')
insert into @friendships values (2,3,'8/24/2008')
insert into @friendships values (4,1,'8/24/2008')
insert into @friendships values (4,5,'8/24/2009')

--all firends
select
    u.*
    FROM @users u
        INNER JOIN (select
                        userid
                        FROM @Friendships
                        WHERE friendid=1
                    UNION
                    select
                        friendid
                        FROM @Friendships
                        WHERE userid=1
                   ) dt ON u.userid=dt.userid



--new firends of friends
select
    u.*
    FROM (select
              userid
              FROM @Friendships
              WHERE friendid=1
          UNION
          select
              friendid
              FROM @Friendships
              WHERE userid=1
         ) dt
        INNER JOIN @friendships f ON dt.userid=f.userID
        INNER JOIN @users u ON f.friendid=u.userid
    WHERE f.datecreated>=GETDATE()-14 --2 weeks

<强>输出

userid      name       profilepic
----------- ---------- ----------
2           matt       m
3           steve      s
4           fred       f

(3 row(s) affected)

userid      name       profilepic
----------- ---------- ----------
5           joe        j

(1 row(s) affected)

答案 4 :(得分:0)

这将显示您朋友的新朋友,哪些新朋友不是您自己的朋友

SELECT DISTINCT fof.* 
FROM
(
  SELECT u.userid AS id, u.name, u.profilepic
  FROM users u
  JOIN friendships my_friends_friends
    ON my_friends_friends.friendid = u.userid
  JOIN friendships my_friends
    ON my_friends.friendid = my_friends_friends.userid
  WHERE
    my_friends.userid = 1
    AND
    my_friends_friends.datecreated > CURRENT_DATE - INTERVAL '10 DAY'
) fof
LEFT JOIN 
( 
  SELECT friendships.friendid 
  FROM friendships WHERE friendships.userid = 1
) f
  ON f.friendid = fof.id
WHERE
  f.friendid IS NULL
;

警告:使用此查询可能会让DISTINCT警察遇到麻烦。 :)