2009-08-24 12 views
1

私は私達のウェブサイトにソーシャルネットワーキング要素をコード化しようとしています。 2つのテーブルがあり、1つはユーザーを示し、もう1つはそのユーザー間の友情を示しています。"friend feed"のための厄介なSQLクエリ

Users: 
userid - PK, int 
name 
profilepic 

Friendships: 
id - PK int 
userid 
friendid 
datecreated 

友情テーブルが双方向である - つまり、誰かが彼らが戻って

それらをfriendingせずに誰かに仲良くなることができ、私はユーザーのすべての友達をフェッチするクエリを必要とする、彼らによって作られた新しい友情友人、そして新しい友情の名前とプロフィールのです。

悪夢!すべての助けが大いに感謝!

答えて

0

これは、純粋なSQLで行うべきことではありません。あなたの関係が今ではっきりと定義されているかもしれませんが、あなたは "フィード"上のアイテムのリストに物を追加したいかもしれません。このコードは、消費コードに集約されるのに適しています。

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 

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

右、あなたは、ここで友人の情報と1対1に二つの異なるクエリを持っています新しい友達の情報のために。それらを一緒にやろうとする真実はありません。

ユーザーのすべての友達OK、それは友人の - 友人関係だ彼らの友人

によって行われている

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

新しい友情、あなたは友情テーブルを2回通って見つけることができます。これは自己結合と呼ばれている:

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

これは新しい友達が既に独自の友人ではありませんあなたの友人の新しい友達、表示されます:

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とのトラブルで:)

関連する問題