2012-04-26 4 views
0

私は2つのテーブル:UserUser2Friendを持っています。私はユーザーの友人を取得する必要があります。クエリではFriendId:FriendIdUserIdという2つの列を処理する必要があります。なぜ誰が誰を追加したのかわからないからです。結果では両方とも友人です。ユーザーフレンドを取得する、サブクエリー、パフォーマンス

クエリ:

SELECT DISTINCT 
    `Id` 
    , `UserName` 
FROM `User` 
WHERE `Id` IN 
    (SELECT 
     IF(`UserId` = 25, `FriendId`, `UserId`) -- This important part - friends are always mutual 
    FROM `User2Friend` 
    WHERE `UserId` = 25 
    OR `FriendId` = 25) 
LIMIT 10 

スキーマ:

CREATE TABLE `User` (
    `Id` int(10) unsigned NOT NULL AUTO_INCREMENT, 
    `UserName` varchar(16) DEFAULT NULL, 
    PRIMARY KEY (`Id`) 
) ENGINE=InnoDB DEFAULT CHARSET=utf8; 
CREATE TABLE `User2Friend` (
    `Id` int(11) unsigned NOT NULL AUTO_INCREMENT, 
    `UserId` int(10) unsigned NOT NULL, 
    `FriendId` int(10) unsigned NOT NULL, 
    PRIMARY KEY (`Id`), 
    UNIQUE KEY `UserIdFriendId` (`UserId`, `FriendId`) 
) ENGINE=InnoDB DEFAULT CHARSET=utf8; 

、そのユーザBがユーザAを持っている必要があります後、ユーザーAが友人として、ユーザBを追加した場合、ユーザーBがユーザーに友達リストを表示されます友達リストにも。サブクエリでLIMITを使用することができないため、サブクエリアプローチは本当に好きではありません。

私は数百万人のユーザーを期待しているため、パフォーマンスが重要です。

このクエリを2つの別々のクエリに分割する方が良いと思いますか?

または、私はトリッキーなJOINを持っている必要がありますか?

+0

テーブルの構造を入れてください –

+0

ここにあなたは...^ –

答えて

0

大丈夫です!私は2つのクエリに分割しました...

0
$sql1 = ("SELECT Id, UserName FROM User WHERE UserId = 25"); 
foreach($sql1 as $row){ 
    $id  = $row['Id']; 
    $name = $row['UserName']; 
     $sql2 = ("SELECT * FROM User2Friend WHERE FriendId = $id LIMIT 10"); 
     foreach($sql2 as $row){ 
      $FriendId = $row['FriendId']; 
      $FriendName = $row['FriendName']; 
     } 
} 

私がよく理解しているかどうかは分かりませんが、これが問題を解決するかどうかはわかりません。

+0

1.すべての友人IDの代わりにID 25を最初に選択したため、あなたの例は間違っています。 2.実際には、ルックアップテーブルのFriendIdとUserIdの2つの列を考慮する必要があります。誰が誰を追加したかによって... –

0

User2Friendテーブルのデフォルト値(N)で3番目のフィールド(Accepted)を作成すると、友だちBを追加するとこの友人をリストでき、友だちを確認して受け入れることができます。

+0

'User2Friend'というテーブルを追加する必要はありません。 –

関連する問題