使用 MySQL,我想列出所有没有文档“联络员”的用户。这可能意味着根本没有任何文档的用户,或者有文档但在这些文档中没有“联络人”的用户。
如何使用 MySQL 查询?我不能让它工作!
这是(简单)模型
Users (id, name)
Documents (id, user_id, name, path)
您正在寻找的正确查询是:
SELECT
*
FROM
Users
WHERE
id NOT IN (
SELECT
user_id
FROM
Documents
WHERE
name = "liaison"
)
这将达到您正在寻找的确切结果。如果特定用户没有文档,它将被列出。如果它有很多文件,其中之一是“联络”,则不会列出。
如果您想在文档名称中搜索“联络员”,请替换name = "liaison"
为name LIKE "%liaison%"
.
它基本上说:选择所有用户,例如没有名称为“liaison”的文档指向它。
这NOT EXISTS
是一个可行的解决方案。作为替代方案,有时,对于大型集合,“反 JOIN”操作可以提供更好的性能:
SELECT u.*
FROM Users u
LEFT
JOIN (SELECT d.user_id
FROM Documents d
WHERE d.name = 'liaison'
) l
ON l.user_id = u.id
WHERE l.user_id IS NULL
别名为的内联视图l
返回给我们一个包含名为“liaison”的文档的 user_id 列表;该结果集外部连接到 Users 表,然后我们排除找到匹配项的任何行(l.user_id 的测试为 NULL)。
这将返回一个与您的带有NOT EXISTS
谓词的查询等效的结果集。
另一种选择是使用带有NOT IN
谓词的查询。请注意,我们需要保证子查询不返回 NULL,因此一般方法是在子查询返回的列上包含一个 IS NOT NULL 谓词。
SELECT u.*
FROM Users u
WHERE u.id NOT IN
( SELECT d.user_id
FROM Documents d
WHERE d.user_id IS NOT NULL
AND d.name = 'liaison'
)
我会这样写NOT EXISTS
查询:
SELECT u.*
FROM Users u
WHERE NOT EXISTS
( SELECT 1
FROM Documents d
WHERE d.name = 'liaison'
AND d.user_id = u.id
)
我个人的偏好是在相关子查询的 SELECT 列表中使用文字 1;它提醒我查询只是在寻找 1 行的存在。)
同样,我通常发现“反连接”模式在大集合中表现最好。(您需要查看每个语句的 EXPLAIN 输出,并测量每个语句的性能以确定哪个最适合您的情况。)
select * from Users where not exists (select id from Documents where Users.id = Documents.id and Documents.name = 'liaison')
所以,我终于想出了这个似乎很好用的解决方案:
SELECT * FROM users u WHERE id NOT IN (SELECT DISTINCT user_id FROM user_documents WHERE name = 'LIAISON') ORDER BY c.lastname, c.firstname
SELECT users.*
FROM users left join Documents
on users.id = Documents.user_id
and documents.name='LIAISON'
WHERE documents.user_id is null
尝试 :
SELECT DISTINCT u.*
FROM users u LEFT JOIN documents d ON d.user_id = u.id
WHERE d.id IS NULL OR d.name NOT LIKE '%liaison%'
如果“联络”是文档的确切名称,则删除百分号。