我有类似朋友表的东西。它被称为contacts
。它有:
user_id
是用户的ID,就像该联系人的所有者一样,contact_id
是与user_id
; 第二个表名为events
。它有:
user_id
是该事件的创建者的用户ID。我需要选择朋友创建的活动。所以如果我的联系人列表中有John和Anna ......我需要显示它们的事件。
这是解决方案:
SELECT `bio_community_events`.`id`,
`bio_community_events`.`begin_on`,
`bio_community_events`.`name`
FROM `bio_community_events`
JOIN `bio_contacts` ON (`bio_contacts`.`contact_id` = `bio_community_events`.`user_id`)
WHERE `bio_contacts`.`user_id` = '33'
即,我的身份证是33
。它给了我朋友们的活动。这就是问题......
有些情况下,我不是与朋友联系的人。反之亦然,安娜做到了。此查询将忽略该查询,并且不显示Anna的结果。
答案 0 :(得分:2)
SELECT `bio_community_events`.`id`,
`bio_community_events`.`begin_on`,
`bio_community_events`.`name`
FROM `bio_community_events`
JOIN `bio_contacts`
ON (`bio_contacts`.`contact_id` = `bio_community_events`.`user_id`)
WHERE `bio_contacts`.`user_id` = '33'
UNION ALL --- or UNION if this gives you
--- duplicate row
SELECT `bio_community_events`.`id`,
`bio_community_events`.`begin_on`,
`bio_community_events`.`name`
FROM `bio_community_events`
JOIN `bio_contacts`
ON (`bio_contacts`.`user_id` = `bio_community_events`.`user_id`)
WHERE `bio_contacts`.`contact_id` = '33'
或者像这样:
SELECT `bio_community_events`.`id`,
`bio_community_events`.`begin_on`,
`bio_community_events`.`name`
FROM `bio_community_events`
JOIN
( SELECT `bio_contacts`.`contact_id` AS id
FROM `bio_contacts`
WHERE `bio_contacts`.`user_id` = '33'
UNION ALL
SELECT `bio_contacts`.`user_id` AS id
FROM `bio_contacts`
WHERE `bio_contacts`.`contact_id` = '33'
) AS un
ON ( un.id = `bio_community_events`.`user_id`)
要为示例#1中的所有返回行设置限制,请使用:
( SELECT ... )
UNION ALL
( SELECT ... )
ORDER BY ? --- optional
LIMIT x ;
使用ORDER BY
在这样的查询中可能会非常昂贵。您还可以使用此(不同)查询来使用索引:
( SELECT ...
ORDER BY ?
LIMIT a
)
UNION ALL
( SELECT ...
ORDER BY ?
LIMIT b
)
LIMIT x ; --- with or without this LIMIT
解决原始问题的另一种方法是使用EXISTS
:
SELECT `bio_community_events`.`id`,
`bio_community_events`.`begin_on`,
`bio_community_events`.`name`
FROM `bio_community_events`
WHERE EXISTS
( SELECT *
FROM `bio_contacts`
WHERE `bio_contacts`.`user_id` = '33'
AND `bio_contacts`.`contact_id` = `bio_community_events`.`user_id`
)
OR EXISTS
( SELECT *
FROM `bio_contacts`
WHERE `bio_contacts`.`contact_id` = '33'
AND `bio_contacts`.`user_id` = `bio_community_events`.`user_id`
)
或:
SELECT `bio_community_events`.`id`,
`bio_community_events`.`begin_on`,
`bio_community_events`.`name`
FROM `bio_community_events`
WHERE EXISTS
( SELECT *
FROM `bio_contacts`
WHERE ( `bio_contacts`.`user_id` = '33'
AND `bio_contacts`.`contact_id` = `bio_community_events`.`user_id` )
OR ( `bio_contacts`.`contact_id` = '33'
AND `bio_contacts`.`user_id` = `bio_community_events`.`user_id` )
)
如果您的计划是找到最有效的查询,请尝试所有正常工作(使用IN,使用UNION,使用EXISTS) - 添加您想要的ORDER BY
- 并检查其速度和执行计划。
我至少会:
bio_community_events
中的user_id
ORDER BY
和
bio_contacts
中的(contact_id, user_id)
和(user_id, contact_id)
并发布另一个问题,如果你不能让它在不到X毫秒的时间内运行(X由你的老板决定:)
答案 1 :(得分:1)
SELECT id, begin_on, name
FROM bio_community_events
WHERE user_id IN ( SELECT user_id FROM bio_contacts WHERE contact_id = '33')
OR user_id IN ( SELECT contact_id FROM bio_contacts WHERE user_id = '33')
答案 2 :(得分:0)
您还需要获取朋友的用户ID:
SELECT `bio_community_events`.`id`, `bio_community_events`.`begin_on`, `bio_community_events`.`name`
FROM `bio_community_events`
JOIN `bio_contacts`
ON (`bio_contacts`.`contact_id` = `bio_community_events`.`user_id`)
WHERE `bio_contacts`.`user_id` = '33'
OR `bio_contacts`.`user_id` IN (SELECT `contact_id` FROM `contacts` WHERE `user_id` = 33)