选择第一列中不存在第二列值的行

Rey*_*rPM 4 mysql join

我有这个表结构:

 id1 id2
 1   2 
 1   3
 1   4
 2   1
 2   5
Run Code Online (Sandbox Code Playgroud)

我需要构建一个查询来选择id2where id1is not in id2. 例如,如果id1 = 1只有id2=3id2=4
我试过这个:

SET @a=1;
SELECT DISTINCT x.id2 
 FROM tt x, tt y 
 WHERE x.id1=@a AND x.id1 != y.id2;
Run Code Online (Sandbox Code Playgroud)

但它不起作用。

Erw*_*ter 9

对于单个给定的简单情况id1

SELECT DISTINCT x.id2   -- DISTINCT only needed if there are dupes
FROM   tbl x
WHERE  x.id1 =  @a
AND    x.id2 <> @a;
Run Code Online (Sandbox Code Playgroud)

一般来说,基本上有四种技术可以做你所追求的事情。两列也可以在不同的表中,几乎是相同的问题。

NOT EXISTS

SELECT DISTINCT x.id2 
FROM   tbl x
WHERE  <some condition>
AND    NOT EXISTS (
    SELECT FROM tbl y
    WHERE  <some condition>
    AND    y.id1 = x.id2
    );
Run Code Online (Sandbox Code Playgroud)

LEFT JOIN / IS NULL

SELECT DISTINCT x.id2 
FROM   tbl x
LEFT   JOIN tbl y ON y.id1 = x.id2
                 AND <some condition for y>
WHERE  <some condition for x>
AND    y.id1 IS NULL
Run Code Online (Sandbox Code Playgroud)

EXCEPT

SELECT DISTINCT id2
FROM   tbl
WHERE  <some condition>

EXCEPT ALL            -- ALL to make it faster - no dupes left after DISTINCT
SELECT tbl.id1
FROM   tbl
WHERE  <some condition>
Run Code Online (Sandbox Code Playgroud)

NOT IN

SELECT DISTINCT x.id2 
FROM   tbl x
WHERE  <some condition>
AND    x.id2 NOT IN (
    SELECT DISTINCT id1
    FROM   tbl y
    WHERE  <some condition>
    );
Run Code Online (Sandbox Code Playgroud)

你必须测试哪一个对你来说最快。基准不同意。这取决于数据分布和其他细节。NOT IN很少赢。它主要是前两个之一。

正如@ypercube 评论的那样:如果(id1, id2)是唯一的,DISTINCT则不需要该子句 - 除了NOT IN子查询中的那个,它旨在帮助提高性能。

关于 PostgreSQL 的更多详细信息的相关答案: