我有以下查询
SELECT * FROM collection
WHERE id = 1 AND (
privacy = 0
OR (privacy = 1 AND
EXISTS (SELECT * FROM collection_member WHERE collection_id = collection.id AND member_id = 1)
)
)
这很好。但是我也想从SELECT * FROM collection_member WHERE collection_id = collection.id AND member_id = 1
输出结果。使用联接实现不的最有效方法是什么? (编辑:可能是subquery encapsulation?)
答案 0 :(得分:2)
这里是将subselect列为一列的版本。
这仍然是联接,但也许更接近您的需求。
SELECT C.* ,
(SELECT MAX(M.MyColumn)
FROM collection_member M
WHERE collection_id = C.id
AND M.member_id = 1
) MyColumn
FROM collection C
WHERE C.id = 1
AND (
C.privacy = 0
OR (privacy = 1 AND
EXISTS (
SELECT * FROM collection_member CM
WHERE CM.collection_id = C.id AND CM.member_id = 1)
)
)
这种方法相对于执行JOIN
的唯一好处是,确保不加入多对多和重复计算会更容易一些。
上面显示的查询使用MAX
以确保仅返回一行。这可能是您想要的行,也可能不是。
答案 1 :(得分:1)
您无法“从exists
子查询中获取值”。
您必须加入:
SELECT *
FROM collection
LEFT JOIN collection_member ON privacy = 0
OR (privacy = 1
AND collection_id = collection.id
AND member_id = 1
)
WHERE id = 1
当然,与您的查询不同,collection
行将在collection_member
中的每个匹配行中出现一次。您可以通过汇总所有collection_member
值来解决此问题。
答案 2 :(得分:0)
尝试一下
SELECT c.*, cm.*
FROM collection c
Left Join collection_member cm on (cm.collection_id = c.collection.id and cm.member_id = 1)
WHERE case
when c.privacy = 0 Then 1
when c.privacy = 1 and cm.collection_id is not null Then 1
else 0
end = 1
and c.id = 1