我有三个表,一个用户,一个案例,一个用户和案例之间的链接。可以将多个用户链接到案例。例如,假设有问题的用户ID是“18”:
CASES
id | other columns
-------------------------
001 | n/a
002 | n/a
003 | n/a
LINKS
case_id | user_id
-------------------------
001 | 12
001 | 18
003 | 06
002 | 05
如您所见,案例001有两个用户链接,一个是我们的用户“18”,另外两个没有用户“18”链接。
所以问题是 - 如何选择没有用户ID 18链接的所有情况? (结果将是案例002和003,因为没有行将这些案例链接到用户18)
答案 0 :(得分:2)
可以使用NOT EXISTS
SELECT id FROM Cases C
WHERE NOT EXISTS (
SELECT * FROM Links L WHERE L.case_id = C.id AND L.user_Id = @userId)
答案 1 :(得分:2)
SELECT
返回所有案例,LEFT JOIN
从链接表中获取匹配且适用于用户18的案例,WHERE
子句过滤掉已连接的行。
SELECT *
FROM CASES
LEFT JOIN LINKS
ON LINKS.case_id = CASES.id
AND LINKS.user_id = 18
WHERE LINKS.case_id IS NULL
考虑在LINKS上添加复合索引('case_id','user_id')。假设它是唯一的,你可以把它作为主键。
答案 2 :(得分:0)
您可能需要一个重构查询,在连接到CASES表之前先收集密钥:
SELECT B.* FROM
(
SELECT CaseIDs.case_id id FROM
(SELECT id case_id FROM CASES) CaseIDs
LEFT JOIN
(SELECT case_id FROM LINKS WHERE user_id = 18) CaseLinks
USING (case_id)
WHERE CaseLinks.case_id IS NULL
) A
LEFT JOIN CASES B USING (id);
您需要适当的覆盖索引
ALTER TABLE LINKS ADD INDEX case_user_index (case_id,user_id);
试一试!!!