【问题标题】:SQL Not Exists include null valueSQL Not Exists 包含空值
【发布时间】:2020-10-15 05:11:07
【问题描述】:

我有两个 SQL Server 表:

表 1

Id name   description     version
----------------------------------
1  Book1  Book 1 Title    v1
2  Book2  Book 2 Title    v2
3  Book3  Book 3 Title    NULL
4  Book5  Book 5 Title    v3

表 2

Id name   description     version
----------------------------------
1  Book1  Book 1 Title    v1
2  Book2  Book 2 Title    v2
3  Book3  Book 3 Title    NULL
4  Book4  Book 4 Title    NULL
5  Book5  Book 5 Title    NULL

我想从表 2 中选择表 1 中不存在的所有数据,这样我就可以 将它们插入另一个表。

这是 SQL 查询:

SELECT t2.name, t2.description, t2.version
FROM Table2 AS t2
WHERE  
    NOT EXISTS (SELECT t1.name, t1.description, t1.version 
                FROM Table1 as t1 
                WHERE t2.name = t1.name 
                  AND t2.description = t1.description  
                  AND t2.version = t1.version)

预期的结果是这样的:

Id name   description     version
-----------------------------------
4  Book4  Book 4 Title    NULL
5  Book5  Book 5 Title    NULL

但我得到的是这个:

Id name   description     version
---------------------------------
3  Book3  Book 3 Title    NULL
4  Book4  Book 4 Title    NULL

为什么我的NOT EXIST 语句中没有计算空值并显示出来?

【问题讨论】:

标签: sql-server sql-server-2014


【解决方案1】:

NULL 值与任何值比较时将返回 FALSE。你需要使用IS NULL来处理

select t2.name, t2.description, t2.version
from   Table2 as t2
WHERE  NOT EXISTS 
       ( 
            SELECT *
            FROM   Table1 as t1 
            WHERE  t2.name        = t1.name 
            AND    t2.description = t1.description 
            AND    (
                       t2.version     = t1.version
                   OR  (t2.version IS NULL AND t1.version IS NULL)
                   )
       )

【讨论】:

  • 如果我在 table2 中有 null 版本而不在 table1 中,这将不起作用。查看我更新的帖子
  • 这个查询没有给出你预期的结果吗?
  • 它没有,因为版本为 null 导致表 2 中的 ID 5 丢失
  • 我试过了,它确实给出了与您发布的相同的预期结果
  • mm 很奇怪。让我再测试一下。当我测试时我的咖啡没有那么浓,我猜哈哈。
【解决方案2】:

优化查询:

SELECT t2.name, t2.description, t2.version 
FROM Table2 AS t2
LEFT JOIN Table1 AS t1 
ON t2.name = t1.name 
 AND t2.description = t1.description  
 AND (t2.version     = t1.version
     OR  (t2.version IS NULL AND t1.version IS NULL))
WHERE t1.ID is NULL

【讨论】:

  • 最好像这样使用NVL NVL(t2.version, '-') = NVL(t1.version, '-')
【解决方案3】:

你可以使用 EXCEPT 来解决这个问题。 您可以使用两个表中的公共字段,然后从该结果中选择您的数据。

看看下面的代码:

SELECT name, description, version FROM Table2
EXCEPT
SELECT name, description, version FROM Table1

此代码为您提供 table2 中存在但 table1 中不存在的数据。

【讨论】:

  • 我必须比较名称、标题和版本,而不是 ID
  • 您只需要命名您的列。及其作品。它也考虑空值。请先测试此代码。然后回复。谢谢
  • EXCEPT 的问题是我不能选择比我的 EXCEPT 查询中指定的列更多的列,但 NOT EXIST 或 LEFT JOIN 可以选择
  • 我认为您不知道自己想要什么,而我的解决方案涵盖了所有内容。
  • Luv 知道我想要什么并解决了我的问题。祝你有美好的一天
【解决方案4】:

你可以简单地使用ISNULL()函数:

SELECT t2.name, t2.description, t2.version
FROM Table2 AS t2
WHERE  
    NOT EXISTS (SELECT t1.name, t1.description, t1.version 
                FROM Table1 as t1 
                WHERE t2.name = t1.name 
                  AND t2.description = t1.description  
                  AND ISNULL(t2.version,0) = ISNULL(t1.version,0)

【讨论】:

    猜你喜欢
    • 2015-02-17
    • 2022-06-15
    • 2021-08-29
    • 2011-05-26
    • 2013-04-17
    • 1970-01-01
    • 2016-07-22
    • 2021-05-29
    • 2010-11-13
    相关资源
    最近更新 更多