使用Mysql,我想列出所有没有文档“liaison”的用户。它可能意味着根本没有任何文档的用户,或者拥有文档但在这些文档中没有“联络”的用户。
如何使用MySQL Query?我不能让它发挥作用!
这是(简单)模型
Users (id, name)
Documents (id, user_id, name, path)
感谢您的帮助
答案 0 :(得分:2)
您正在寻找的正确查询是:
SELECT
*
FROM
Users
WHERE
id NOT IN (
SELECT
user_id
FROM
Documents
WHERE
name = "liaison"
)
这将达到您正在寻找的确切结果。如果特定用户没有文档,则会列出该文档。如果它有许多文件,其中一个是“联络人”,则不会列出。
如果您想在文档名称中搜索“联络人”,请将name = "liaison"
替换为name LIKE "%liaison%"
。
它基本上说:选择所有用户,例如没有名称为“liaison”的文件指向它。
答案 1 :(得分:2)
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
别名的内联视图返回一个user_id列表,其中包含名为“liaison”的文档;结果集外部连接到Users表,然后我们排除发现匹配的任何行(l.user_id IS 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输出,并测量每个语句的性能,以确定哪种语句在您的情况下最有效。)
答案 2 :(得分:1)
select * from Users where not exists (select id from Documents where Users.id = Documents.id and Documents.name = 'liaison')
答案 3 :(得分:1)
所以,我终于想出了这个似乎运作良好的解决方案:
SELECT * FROM users u WHERE id NOT IN (SELECT DISTINCT user_id FROM user_documents WHERE name = 'LIAISON') ORDER BY c.lastname, c.firstname
答案 4 :(得分:1)
SELECT users.*
FROM users left join Documents
on users.id = Documents.user_id
and documents.name='LIAISON'
WHERE documents.user_id is null
答案 5 :(得分:0)
尝试:
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%'
如果“联络人”是文件的确切名称,请删除百分号。