选择NOT IN多列

Gun*_*gam 61 sql database multiple-columns

我需要实现以下查询

SELECT * 
FROM   friend 
WHERE  ( friend.id1, friend.id2 ) 
         NOT IN (SELECT id1, 
                        id2 
                 FROM   likes) 
Run Code Online (Sandbox Code Playgroud)

但NOT IN无法在多列上实现.我该如何编写此查询

Mic*_*aga 87

我不确定你是否考虑过:

select * from friend f
where not exists (
    select 1 from likes l where f.id1 = l.id and f.id2 = l.id2
)
Run Code Online (Sandbox Code Playgroud)

仅当id1与id1和id2相关且id2与两者都不相关时才有效.

  • 如果 id1 或 id2 包含 NULL 值,这在 SQL Server 中不起作用,您需要使用合并函数:`select 1 from likes l where coalesce(f.id1,​​ 0) = coalesce(l.id1,​​ 0)并合并(f.id2,0)=合并(l.id2,0)` (4认同)

Erw*_*ter 18

另一个神秘未知的RDBMS.你的语法在PostgreSQL中完全没问题.其他查询样式可能执行得更快(尤其是NOT EXISTS变体或a LEFT JOIN),但您的查询完全合法.

NOT IN但是,当涉及任何NULL值时,请注意陷阱:

LEFT JOIN的变体:

SELECT *
FROM   friend f
LEFT   JOIN likes l USING (id1, id2)
WHERE  l.id1 IS NULL;
Run Code Online (Sandbox Code Playgroud)

请参阅@Michał的NOT EXISTS变体答案.
对四种基本变体的更详细评估:


小智 6

我使用了一种可能看起来很愚蠢但对我有用的方法。我只是连接要比较的列并使用 NOT IN:

SELECT *
FROM table1 t1
WHERE CONCAT(t1.first_name,t1.last_name) NOT IN (SELECT CONCAT(t2.first_name,t2.last_name) FROM table2 t2)
Run Code Online (Sandbox Code Playgroud)

  • concat 会给出错误的匹配。(即“ab”、“cd”和“a”、“bcd”) (4认同)
  • 您可以通过使用保证任何列都不会使用的分隔符来避免错误匹配,但更大的问题是,由于使用了 WHERE CONCAT,您的查询需要全表扫描。First_name 或 Last_name 列上的索引对于查询计划程序没有用处。 (2认同)

Rao*_*rge -5

您可能应该用于NOT EXISTS多个列。

  • 如何?您的回答没有提供任何细节。 (2认同)