嵌套 SQL 语句之间的差异

Differences between nested SQL statements

这是我引用的原文

select * 
from CSDokument
where FirmaPubIndex in (select firmapubindex 
                        from CSDokument 
                        where dokumenttyp = '3' 
                          and ProjPubIndex in (select PubIndex 
                                               from CSProjekt 
                                               where Projektnummer = 209806)
                       )
  and ProjPubIndex in (select PubIndex 
                       from CSProjekt 
                       where Projektnummer = 209806)
  and DokumentTyp = '2'

我不明白为什么这两个语句与第一个 where return 不同的结果。我想知道为什么这个语句 returns 9926 results

select firmapubindex
from CSDokument
where FirmaPubIndex in (select firmapubindex 
                        from CSDokument 
                        where dokumenttyp = '3' 
                          and ProjPubIndex in (select PubIndex  
                                               from CSProjekt 
                                               where Projektnummer = 209806)
                       )

而这个 returns 144:

select firmapubindex 
from CSDokument 
where dokumenttyp = '3'
  and ProjPubIndex in (select PubIndex 
                       from CSProjekt 
                       where Projektnummer = 209806)

在 select 来自 CSDokument 这些行中 dokumenttyp='3' 而 ProjPubIndex 在 table CSProjekt 并且 Projektnummer = 209806.

where 子句的第一部分首先获取与 dokumenttyp 一起出现的 firmapubindex 值等于 3。

但是你 select 记录具有这样的 firmapubindex 值。您 得到 dokumenttyp 3 的那些,还有其他的。这就是为什么你得到更多。

想象一下这些数据,假设它们都链接到正确的 CSProjekt:

firmapubindex | dokumenttyp
--------------+------------
    10        |    1
    10        |    2
    10        |    3
    20        |    1
    30        |    3

以下select:

select firmapubindex 
from   CSDokument 
where  dokumenttyp='3' and 
       ProjPubIndex in ( 
         select PubIndex from CSProjekt where Projektnummer = 209806 )

... 将 return:

firmapubindex 
-------------
    10        
    30        

现在看看外面的 select 当你把它包裹起来时做了什么:

select * 
from   CSDokument
where  FirmaPubIndex in 
       (select firmapubindex 
        from   CSDokument 
        where  dokumenttyp='3' and 
               ProjPubIndex in ( 
                  select PubIndex from CSProjekt where Projektnummer = 209806 )
       )

... 它会列出这些记录,因为匹配 firmapubindex:

firmapubindex | dokumenttyp
--------------+------------
    10        |    1
    10        |    2
    10        |    3
    30        |    3

这就是为什么您需要再次过滤 dokumenttyp 值(和 Projektnummer)。

注意事项

现在了解您查询的含义:如果这是完整的图片,那么首先检查 firmapubindex 是否在您要访问的结果集中是没有意义的产生,因为那是重言式(即,总是正确的)。

所以下面两个查询会return相同的结果集:

select * 
from   CSDokument
where  FirmaPubIndex in (
            select firmapubindex 
            from   CSDokument 
            where  dokumenttyp = '3' 
            and    ProjPubIndex in (select PubIndex 
                                    from   CSProjekt 
                                    where  Projektnummer = 209806)
        )
and    ProjPubIndex in (select PubIndex 
                        from   CSProjekt 
                        where  Projektnummer = 209806)
and    DokumentTyp = '3'

和:

select * 
from   CSDokument
where  FirmaPubIndex is not null 
and    ProjPubIndex in (select PubIndex 
                        from   CSProjekt 
                        where  Projektnummer = 209806)
and    DokumentTyp = '3'

is not null 测试仍然是必要的,因为当 in 运算符的左侧是 null 时,它总是会产生 false

这些是不同的查询。考虑

CSDokument
firmapubindex dokumenttyp Projektnummer 
1 3 209806 
1 0 0

第二个查询将 return 只有一行,并且会有 firmapubindex=1。所以这两行都将被第一个查询return编辑。