MySQL选择左连接为空的行

Posted

技术标签:

【中文标题】MySQL选择左连接为空的行【英文标题】:MySQL select rows where left join is null 【发布时间】:2014-11-11 11:42:11 【问题描述】:

我有这些 mysql 表:

表1:

id | writer
1  | Bob   
2  | Marley
3  | Michael

表2:

user_one | user_two
   1     | 2

这个查询:

SELECT table1.id FROM table1 LEFT JOIN table2 ON table1.id = table2.user_one

此查询将返回 table1 的所有行,即 1,2,3

我只想选择左侧关节中找不到的行。所以它应该只返回id为3的行

我想要与 INNER JOIN 相反的类型,它将只选择在连接中找到的行。如果左连接存在,如何获得相反的结果,忽略它并移动到下一行。希望我清楚

【问题讨论】:

添加where table2.user_one is null @GordonLinoff 对我来说,请您解释一下这个逻辑来添加where table2.user_one is null,因为我认为它会同时返回 2 和 3,但用户只想要 3。 table2的结构是什么?两列 user_oneuser_two? 【参考方案1】:

您可以使用以下查询:

SELECT  table1.id 
FROM    table1 
        LEFT JOIN table2 
            ON table1.id IN (table2.user_one, table2.user_two)
WHERE   table2.user_one IS NULL;

不过,根据您在 table2 上的索引,您可能会发现两个连接的性能更好:

SELECT  table1.id 
FROM    table1 
        LEFT JOIN table2 AS t1
            ON table1.id = t1.user_one
        LEFT JOIN table2 AS t2
            ON table1.id = t2.user_two
WHERE   t1.user_one IS NULL
AND     t2.user_two IS NULL;

【讨论】:

【参考方案2】:

如果您不想从table2 返回任何列,最好的方法之一是使用NOT EXISTS

SELECT  table1.id 
FROM    table1 T1
WHERE
  NOT EXISTS (SELECT *
              FROM table2 T2
              WHERE T1.id = T2.user_one
                  OR T1.id = T2.user_two)

从语义上讲,这说明了您要查询的内容:选择第二个表中没有匹配记录的每一行。

MySQL 针对EXISTS 进行了优化:一旦找到第一个匹配记录,它就会返回。

【讨论】:

【参考方案3】:

这是一个查询,它只返回在user_oneuser_twotable2 的两列中没有找到对应的行:

SELECT T1.*
FROM table1 T1
LEFT OUTER JOIN table2 T2A ON T2A.user_one = T1.id
LEFT OUTER JOIN table2 T2B ON T2B.user_two = T1.id
WHERE T2A.user_one IS NULL
    AND T2B.user_two IS NULL

每一列(user_oneuser_two)有一个关节,并且查询只返回没有匹配关节的行。

希望这会对你有所帮助。

【讨论】:

【参考方案4】:
SELECT table1.id 
FROM table1 
LEFT JOIN table2 ON table1.id = table2.user_one
WHERE table2.user_one is NULL

【讨论】:

【参考方案5】:

尝试以下查询:-

 SELECT table1.id 
 FROM table1 
 where table1.id 
 NOT IN (SELECT user_one
         FROM Table2
             UNION
         SELECT user_two
         FROM Table2)

希望对你有所帮助。

【讨论】:

【参考方案6】:

试试:

SELECT A.id FROM
(
  SELECT table1.id FROM table1 
  LEFT JOIN table2 ON table1.id = table2.user_one
  WHERE table2.user_one IS NULL
) A
JOIN (
  SELECT table1.id FROM table1 
  LEFT JOIN table2 ON table1.id = table2.user_two
  WHERE table2.user_two IS NULL
) B
ON A.id = B.id

Demo

或者您可以使用两个带有别名的LEFT JOINS,例如:

SELECT table1.id FROM table1 
 LEFT JOIN table2 A ON table1.id = A.user_one
 LEFT JOIN table2 B ON table1.id = B.user_two
 WHERE A.user_one IS NULL
 AND B.user_two IS NULL

2nd Demo

【讨论】:

以上是关于MySQL选择左连接为空的行的主要内容,如果未能解决你的问题,请参考以下文章

MySQL

MySQL连接5种方式

左连接在 MySQL 中为空

如何与第一个匹配行左连接并用空填充其余部分?

访问为空的左连接成员时的教义痛苦

数据库操作-内连接外连接