0

2人のユーザー間の相互の連絡先を見つけようとしています。連絡先テーブルは次のように設定されます。

userprofile_usercontact
- first_user_id
- second_user_id
- mutual

以下は私が達成しようとしているクエリです:

/* get the first user's contacts */
SELECT second_user_id FROM userprofile_usercontact WHERE first_user_id = 1 AND mutual = 1
   UNION 
SELECT first_user_id FROM userprofile_usercontact WHERE second_user_id = 1 AND mutual = 1
    *INTERSECT*
/* get the second user's contacts */
SELECT second_user_id FROM userprofile_usercontact WHERE first_user_id = 37 AND mutual = 1
    UNION 
SELECT first_user_id FROM userprofile_usercontact WHERE second_user_id = 37 AND mutual = 1

どうすればこれを達成できますか?

4

2 に答える 2

1

相互属性の重要性はわかりませんが、サンプルコードでは常に1であるため、$user1と$user2の間の共通の連絡先(単一の分離度)を見つけるには、データを(内部で)結合するだけです。 。

SELECT user1_contacts.uid
FROM
(SELECT a.first_user_id as uid
 FROM userprofile_usercontact a
 WHERE a.second_user_id=$user1
 AND a.mutual=1
 UNION
 SELECT b.second_user_id
 FROM userprofile_usercontact b
 WHERE b.second_user_id=$user1
 AND b.mutual=1) as user1_contacts,
(SELECT a.first_user_id as uid
 FROM userprofile_usercontact a
 WHERE a.second_user_id=$user2
 AND a.mutual=1
 UNION
 SELECT b.second_user_id
 FROM userprofile_usercontact b
 WHERE b.second_user_id=$user2
 AND b.mutual=1) as user2_contacts
WHERE user1_contacts.uid=user2_contacts.uid

事実上、マージ結合を強制しているので、これは最も効率的な解決策ではない可能性があります(ただし、「IN」と「OR」を使用するよりもはるかに効率的です。ネストされたルックアップを使用してすべてを記述できますが、コードは非常に乱雑になります。

単一の分離度を超えたい場合は、グラフに最適化されたDBMSを使用する方がはるかにクリーンです。

于 2012-06-06T10:28:15.053 に答える
0

これはきれいではありませんが、機能するはずです。

SELECT * FROM userprofile_usercontact 
WHERE 
(
first_user_id IN
(
/* get the first user's contacts */
SELECT second_user_id FROM userprofile_usercontact WHERE first_user_id = 1 AND mutual = 1
   UNION 
SELECT first_user_id FROM userprofile_usercontact WHERE second_user_id = 1 AND mutual = 1
) AND first_user_id IN (
/* get the second user's contacts */
SELECT second_user_id FROM userprofile_usercontact WHERE first_user_id = 37 AND mutual = 1
    UNION 
SELECT first_user_id FROM userprofile_usercontact WHERE second_user_id = 37 AND mutual = 1
)
) OR (
second_user_id IN
(
SELECT second_user_id FROM userprofile_usercontact WHERE first_user_id = 1 AND mutual = 1
   UNION 
SELECT first_user_id FROM userprofile_usercontact WHERE second_user_id = 1 AND mutual = 1
) AND second_user_id IN (
/* get the second user's contacts */
SELECT second_user_id FROM userprofile_usercontact WHERE first_user_id = 37 AND mutual = 1
    UNION 
SELECT first_user_id FROM userprofile_usercontact WHERE second_user_id = 37 AND mutual = 1
)
)
于 2012-06-06T09:51:48.047 に答える