2009-08-24 5 views
1

Ich versuche, ein Social-Networking-Element auf unserer Website zu kodieren. Wir haben zwei Tabellen, eine zeigt Benutzer und eine zeigt Freundschaften zwischen diesen Benutzern.Unklare SQL-Abfrage für "Friend Feed"

Users: 
userid - PK, int 
name 
profilepic 

Friendships: 
id - PK int 
userid 
friendid 
datecreated 

Die Freundschaft Tisch ist Zwei-Wege - also jemand jemand anfreunden kann, ohne sie zu ihnen zurück

friending brauche ich eine Abfrage, die alle Freunde für einen Benutzer holen wird, neue Freundschaften, die durch ihr gemacht wurden Freunde, und die Namen der neuen Freundschaften und profilepic's.

Ein Albtraum! Alle Hilfe sehr geschätzt!

Antwort

0

Dies sollte nicht in reinem SQL erfolgen. Während Ihre Beziehungen jetzt vielleicht trivial definiert sind, können Sie (wollen?) Etwas zur Liste der Elemente im "Feed" hinzufügen. Dieses Etwas ist viel besser geeignet, um in dem konsumierenden Code aggregiert zu werden.

0

versuchen, diesen (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 

OUTPUT

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) 
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

Recht, haben Sie zwei hier verschiedene Abfragen erhalten, die einen für Freund info und einer für neue Freund-von-Freund Info. Es gibt keinen wirklichen Sinn, sie zusammen zu machen.

alle für einen Benutzer Freunde

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

neue Freundschaften, die

OK von ihren Freunden gemacht wurden, das ist ein Freund-of-a-friend-Beziehung, was du finden kannst, wenn du zweimal durch den Freundschaftstisch gehst. Das eine nennt sich selbst verbinden:

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] 
0

Diese Ihres Freundes neue Freunde zeigen, die neuen Freunde sind nicht bereits eigene Freunde:

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 
; 

Warnung: Diese Abfrage können Sie erhalten in Schwierigkeiten mit der Polizei DISTINCT. :)