【问题标题】:MySQL select rows where left join is nullMySQL选择左连接为空的行
【发布时间】:2025-11-27 04:35:02
【问题描述】:

我有这些 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?

标签: mysql sql join left-join


【解决方案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

            【讨论】: