嵌套SQL语句之间的差异

时间:2017-03-18 13:02:37

标签: sql sql-server nested where

这是我引用的原始陈述

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的这两个陈述会返回不同的结果。我想知道为什么这句话会返回9926结果

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

这会返回144:

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

在两者中,我从CSDokument选择dokumenttyp =' 3' ProjPubIndex位于表格CSProjekt中,且Projektnummer = 209806。

2 个答案:

答案 0 :(得分:2)

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

但是您选择了具有 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 )

...将返回:

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 是否在你将要生成的结果集中是没有意义的,因为那样是一个重言式(即,总是如此)。

因此,以下两个查询将返回相同的结果集:

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运算符的左侧是false时,它始终会产生null

答案 1 :(得分:1)

这些是不同的查询。考虑

CSDokument
firmapubindex dokumenttyp Projektnummer 
1 3 209806 
1 0 0

第二个查询只会返回一行,而且会有firmapubindex=1。因此,第一个查询将返回两行。