2012-01-08 64 views
1

所以,我有這兩個表:構建基本好友系統:獲取所有好友查詢

user table: 
id, username 
10, hovercraft 
11, mine_craft 

friendship table: 
id, user_id, friend_id 
1, 10,  11 

現在我有這樣的SQL查詢:

SELECT `friends`.`id`, 
`friends`.`username`, 
FROM `users` AS `u` 
JOIN `friendships` AS `fs` 
ON (`fs`.`user_id` = `u`.`id`) 
JOIN `users` AS `friends` 
ON (`friends`.`id` = `fs`.`friend_id`) 
WHERE `fs`.`user_id` = '10' 
OR `fs`.`friend_id` = '10' 

在我想爲朋友一個特定的user_id。但是,此查詢無法創建「雙向」檢索,因爲當我提供user_id 11時,沒有朋友出現。

有沒有辦法解決這個問題?

編輯:我忘了補充一點friend_id還引用了用戶表

回答

1

新增,更好的版本(我認爲) :

select u.id, username 
from user u 
left join friendship f1 on u.id = f1.user_id 
left join friendship f2 on u.id = f2.friend_id 
where coalesce(f1.friend_id, f2.user_id, u.id) <> u.id and 
    coalesce(f1.friend_id, f2.user_id, u.id) = 10 

比這個查詢(如放置在前):

select id, username from (
    select u.id, username, case when f.friend_id <> u.id then f.friend_id else f.user_id end as friend_id 
    from user u 
    join friendship f on u.id = f.user_id 
    union 
    select u.id, username, case when f.friend_id <> u.id then f.friend_id else f.user_id end as friend_id 
    from user u 
    join friendship f on u.id = f.friend_id 
) t where friend_id = 10 
+0

這是真棒,雖然這是第一次我用聚結。我需要時間研究它:D – yretuta 2012-01-28 22:21:04

1

你開始你的查詢有點太深ID。由於友誼表中有一個字段,你可以在尋找的用戶ID,然後開始查詢那裏,只有加入了用戶表中選擇朋友:

SELECT u."id", u."username" 
FROM "friendships" AS f 
JOIN "users" AS u ON f.friend_id = u."friend_id" 
WHERE f."user_id" = 11 
+0

試過這種替代%d,無法正常工作。我編輯的問題 – yretuta 2012-01-09 03:14:25

0

這裏是我的解決方案:難點在於,因爲朋友r中正確的請求equests可以跨越(如果A要求B或B詢問A將以相反的方式存儲在表格的「to」和「from」字段中)。讓我們這樣做,並使用UNION和別名來從任何用戶那裏獲得獨立於關係表下面的朋友。

  1. 的[朋友]表(關係):以|從| statut(待定,確認)
  2. 「到」 和 「從」> foreign_keys約束到[用戶]表

下面的請求總是給出想要的結果! (用戶ID或用戶ID在SESSION

SELECT 
    users.userNickname, 
    friends.to AS friendUser, 
    friends.from AS currentUser, 
    friends.statut 
    FROM 
    users 
     INNER JOIN 
     friends 
     ON 
     users.userId = friends.to 
    WHERE 
    friends.from = '%d' 
UNION 
    SELECT 
    users.userNickname, 
    friends.from AS friendUser, 
    friends.to AS currentUser, 
    friends.statut 
    FROM 
    users 
     INNER JOIN 
     friends 
     ON 
     users.userId = friends.from 
    WHERE 
    friends.to = '%d'