SQL查询排除一对多具有特定值的SQL?

时间:2012-12-17 16:11:28

标签: mysql sql

使用Mysql,我想列出所有没有文档“liaison”的用户。它可能意味着根本没有任何文档的用户,或者拥有文档但在这些文档中没有“联络”的用户。

如何使用MySQL Query?我不能让它发挥作用!

这是(简单)模型

Users (id, name)
Documents (id, user_id, name, path)

感谢您的帮助

6 个答案:

答案 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%'

如果“联络人”是文件的确切名称,请删除百分号。