挑战mysql INTERSECT查询

时间:2012-06-06 03:39:15

标签: mysql sql

我试图找到两个用户之间的相互联系。联系人表格设置如下:

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

我将如何实现这一目标?

2 个答案:

答案 0 :(得分: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'更有效。可以使用嵌套来编写整个东西查找,但代码会变得非常混乱。

如果你想要超越单一程度的分离,那么使用graph optimised DBMS

会更加清晰

答案 1 :(得分: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
)
)