【问题标题】:Select NOT IN multiple columns选择 NOT IN 多列
【发布时间】:2011-12-23 10:23:08
【问题描述】:

我需要实现以下查询:

SELECT * 
FROM   friend 
WHERE  ( friend.id1, friend.id2 ) 
         NOT IN (SELECT id1, 
                        id2 
                 FROM   likes) 

但是NOT IN 不能在多列上实现。如何编写此查询?

【问题讨论】:

  • 您的代码是有效的标准完整 SQl-92 语法。您只在问题中添加了“sql”标签。如果您指的是特定产品(例如 SQL Server),那么您应该找到它的特定标签(SQL Server 不支持该语法,顺便说一句)。
  • 这会是 OpenEdge 吗?不幸的是,Open Edge 没有实现完整的 SQL-92 规范,not innot exists 都不起作用,只有 left join where = null 策略可以与 OpenEdge 一起使用。

标签: sql database multiple-columns


【解决方案1】:

我使用了一种可能看起来很愚蠢但对我有用的方法。 我只是连接我想要比较的列并使用 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)

【讨论】:

  • concat 会给出错误的匹配。 (即“ab”、“cd”和“a”、“bcd”)
  • 所以可以在中间加一个分隔符,比如 "ab" + "/" + "cd"
  • 您可以通过使用保证不会被任一列使用的分隔符来避免错误匹配,但更大的问题是由于您使用了 WHERE CONCAT,您的查询需要进行全表扫描。 first_name 或 last_name 列上的索引对查询计划器没有用处。
【解决方案2】:

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

【讨论】:

  • 怎么样?您的回答没有提供任何细节。
【解决方案3】:

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

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

带有 LEFT JOIN 的变体:

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

查看@Michał 对NOT EXISTS 变体的回答。
对四种基本变体的更详细评估:

【讨论】:

  • 删除了简化的 EXISTS。最好使用标准格式。
【解决方案4】:

我不确定你是否考虑过:

select * from friend f
where not exists (
    select 1 from likes l where f.id1 = l.id and f.id2 = l.id2
)

仅当 id1 与 id1 相关且 id2 与 id2 相关时才有效。

【讨论】:

  • 它在我的情况下有效。我只是想排除其 A 和 B 列存在于排除表中的行。 SQL Server 2016。
  • 它适用于 MySQL 我用它而不是 EXCEPT,因为 MySQL 不支持 EXCEPT 语法
  • 如果 id1 或 id2 包含 NULL 值,这在 SQL Server 中不起作用,您需要使用合并函数:select 1 from likes l where coalesce(f.id1, 0) = coalesce(l.id1, 0) and coalesce(f.id2, 0) = coalesce(l.id2, 0)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-07-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-02-11
  • 2021-05-18
  • 1970-01-01
相关资源
最近更新 更多