SQL Server 2005 - WHERE NOT EXISTS 和 NOT EXISTS 内的复杂脚本

Posted

技术标签:

【中文标题】SQL Server 2005 - WHERE NOT EXISTS 和 NOT EXISTS 内的复杂脚本【英文标题】:SQL Server 2005 - WHERE NOT EXISTS and a complicated script inside of the NOT EXISTS 【发布时间】:2014-12-28 05:02:28 【问题描述】:

脚本目标:从一个列表中获取一个数字列表,其中数字没有出现在另一个列表中。

复杂性:其他数字列表只能通过复杂的脚本获得 - 出于某种原因,当我知道应该有结果时却没有得到结果;因为第一个列表将包含所有数字,而第二个数字列表将仅包含一些数字;所以我应该得到一些结果。

我写的剧本(审查)

SELECT A.Number
FROM   sometable AS A
       INNER JOIN othertable AS B
               ON A.Data = B.Data
       INNER JOIN othertable2 AS C
               ON B.Data = C.Data
       INNER JOIN othertable3 AS D
               ON C.Data = D.Data
WHERE  D.Data = 'int'
       AND NOT EXISTS (SELECT DISTINCT A.Number
                       FROM   sometable AS C
                              anothertable AS B
                                      ON C.Data = B.Data
                              INNER JOIN anothertable AS E
                                      ON B.Data = E.Data
                              INNER JOIN anothertable AS A
                                      ON E.Data = A.Data
                              CROSS apply (SELECT DG.Data
                                           FROM   atable AS DG
                                           WHERE  B.Data = DG.Data) D
                       WHERE  D.Data IN ( 'int', 'int', 'int', 'int' )) 

如果我运行第 1 部分(在不存在之前)它工作正常

如果我运行第 2 部分(不存在的数据),它也可以正常工作 - 结果不同且更少(包含第 1 部分中的数字)

但他们没有在一起。所以我需要知道如何做到这一点,如果不存在不是我需要使用的?

【问题讨论】:

您不存在与子查询一起使用,您的子查询使用与外部查询相同的表和别名。这将防止它成为一个相关的子查询,并且可能是您的问题来自哪里。此外,在 IN 列表中包含相同的项目并没有任何用处。 仅供参考:在 EXIST 查询中使用 DISTINCT 是没有用的。查询返回的什么并不重要,只要行数:零或大于零。 看起来子查询中有错字..sometable AS C anothertable AS B.. 应该是..sometable AS C Inner Join anothertable AS B.. 缺少Inner Join 我使用的方法不存在,这是整个问题。我想我现在明白了。 PM 77-1 的回应对我来说很有意义。 @NoDisplayName - 两个查询中的表不一样;但数据将具有可比性。我试图从真实版本中简化。我确实错过了演示脚本中不存在的内部连接声明;但不是真的。 【参考方案1】:

您的查询正在正常工作。由于您的子查询中有存在一些行,因此外部查询没有产生任何结果,但这不是完成目标的正确方法

你的目标

从一个列表中获取一个数字列表,其中数字没有出现在另一个列表中。

可以通过两种方式完成。

使用Not Exists

SELECT A.Number
FROM   sometable AS A
       INNER JOIN othertable AS B
               ON A.Data = B.Data
       INNER JOIN othertable2 AS C
               ON B.Data = C.Data
       INNER JOIN othertable3 AS D
               ON C.Data = D.Data
WHERE  D.Data = 'int'
       AND NOT EXISTS (SELECT 1
                       FROM   sometable AS CC
                              INNER JOIN anothertable AS BB
                                      ON Cc.Data = BB.Data
                              INNER JOIN anothertable AS EE
                                      ON BB.Data = EE.Data
                              INNER JOIN anothertable AS AA
                                      ON EE.Data = AA.Data
                              CROSS apply (SELECT DG.Data
                                           FROM   atable AS DG
                                           WHERE  BB.Data = DG.Data) DD
                       WHERE  DD.Data IN ( 'int', 'int', 'int', 'int' )
                              AND aa.number = a.number)

或者使用Not IN

SELECT A.Number
FROM   sometable AS A
       INNER JOIN othertable AS B
               ON A.Data = B.Data
       INNER JOIN othertable2 AS C
               ON B.Data = C.Data
       INNER JOIN othertable3 AS D
               ON C.Data = D.Data
WHERE  D.Data = 'int'
       AND A.Number NOT IN (SELECT AA.number
                            FROM   sometable AS CC
                                   INNER JOIN anothertable AS BB
                                           ON Cc.Data = BB.Data
                                   INNER JOIN anothertable AS EE
                                           ON BB.Data = EE.Data
                                   INNER JOIN anothertable AS AA
                                           ON EE.Data = AA.Data
                                   CROSS apply (SELECT DG.Data
                                                FROM   atable AS DG
                                                WHERE  BB.Data = DG.Data) DD
                            WHERE  DD.Data IN ( 'int', 'int', 'int', 'int' )
                                   AND aa.number = a.number) 

【讨论】:

谢谢!我想我明白为什么这会起作用而我的不会。我试试看。【参考方案2】:

您说子查询独立运行会产生结果。因此,在NOT EXISTS 子句中运行时,它总是会产生结果,因此该子句将始终为假。

我猜你的意思更像是WHERE A.Number NOT IN ( ... )

【讨论】:

以上是关于SQL Server 2005 - WHERE NOT EXISTS 和 NOT EXISTS 内的复杂脚本的主要内容,如果未能解决你的问题,请参考以下文章

SQL Server 2005 中的原子 UPSERT

在存储过程 sql server 2005 中使用函数调用?

sql2005 中的把2个表创建成一个视图

无法在 View SQL Server 2005 上执行删除

SQL Server 2005 - 内部联接的顺序

sql server 中 like 中文不匹配问题