为什么相同的EXISTS返回不同的结果

时间:2016-11-17 14:36:54

标签: sql-server tsql exists notin

每个PolicyNumber可以有多个ClassCode。因此,目标是消除所有相关列的整个PolicyNumber 如果选择要删除至少一个ClassCode's,则包括所有ClassCode。 我有cte1 PolicyNumberWrittenPremium(WP),我的表tblClassCodesPlazaCommercialPolicyNumberClassCode。 在我的WHERE条款中,我选择:

WHERE       EXISTS (
                    SELECT  DISTINCT PolicyNumber 
                    FROM    tblClassCodesPlazaCommercial 
                    WHERE   PolicyNumber NOT IN (SELECT  PolicyNumber FROM tblClassCodesPlazaCommercial WHERE  ClassCode =5151)
                    )

然后,如果我select * from cte3 WHERE ClassCode =5151我仍然拥有ClassCode 5151的政策

enter image description here

以下整个选择声明:

 select     
                cte1.PolicyNumber,
                cte1.TransactionEffectiveDate,
                cc.ClassCode,
                CASE
                    WHEN ROW_NUMBER() OVER (PARTITION BY cte1.QuoteID, cte1.PolicyNumber, cc.TransactionEffectiveDate ORDER BY (SELECT 0))=1 THEN cte1.WP 
                    ELSE 0
                END  as WP--,
    from        cte1 inner join tblClassCodesPlazaCommercial cc on cte1.PolicyNumber=cc.PolicyNumber AND cte1.QuoteID=cc.QuoteID AND cte1.TransactionEffectiveDate=cc.TransactionEffectiveDate 
    where       EXISTS (SELECT DISTINCT PolicyNumber FROM tblClassCodesPlazaCommercial WHERE PolicyNumber NOT IN (SELECT  PolicyNumber FROM tblClassCodesPlazaCommercial WHERE  ClassCode =5151))

但是,如果我声明@PoliciesThatDontHaveClassCodes表与PolicyNumber没有ClassCode 5151并在我的EXISTS命令中使用它 - 那么它的工作原理。

DECLARE @PoliciesThatDontHaveClassCodes Table (PolicyNumber varchar(100)) 
INSERT INTO @PoliciesThatDontHaveClassCodes SELECT DISTINCT PolicyNumber    FROM tblClassCodesPlazaCommercial 
                                                                            WHERE PolicyNumber NOT IN (SELECT  PolicyNumber FROM tblClassCodesPlazaCommercial WHERE  ClassCode =5151)
select      
            cte1.PolicyNumber,
            cte1.TransactionEffectiveDate,
            cc.ClassCode,
            CASE
                WHEN ROW_NUMBER() OVER (PARTITION BY cte1.QuoteID, cte1.PolicyNumber, cc.TransactionEffectiveDate ORDER BY (SELECT 0))=1 THEN cte1.WP 
                ELSE 0
            END  as WP--,
from        cte1 inner join tblClassCodesPlazaCommercial cc on cte1.PolicyNumber=cc.PolicyNumber 
            AND cte1.QuoteID=cc.QuoteID 
            AND cte1.TransactionEffectiveDate=cc.TransactionEffectiveDate 
where       EXISTS (SELECT * FROM @PoliciesThatDontHaveClassCodes t  WHERE t.PolicyNumber=cc.PolicyNumber )

有什么区别?两个子查询本身返回完全相同的结果集。为什么在第一种情况下它不起作用,但在第二种情况下(当我声明@PoliciesThatDontHaveClassCodes时) - 它有效吗? 如何在不声明任何表变量的情况下实现相同的结果?

1 个答案:

答案 0 :(得分:6)

在您提供的第一个样本中

WHERE EXISTS (SELECT  DISTINCT PolicyNumber 
                FROM    tblClassCodesPlazaCommercial 
                WHERE   PolicyNumber NOT IN (SELECT  PolicyNumber 
                                               FROM tblClassCodesPlazaCommercial 
                                               WHERE  ClassCode =5151))

外部查询和子查询之间没有相关性。因此,我们单独评估子查询,并且由于查询返回一行,因此WHERE EXISTS …始终为真。

在第二个示例中,您将子查询与外部查询相关联,这是t.PolicyNumber = cc.PolicyNumber的作用,因为cc在子查询之外:

WHERE EXISTS (SELECT * FROM @PoliciesThatDontHaveClassCodes t  
               WHERE t.PolicyNumber=cc.PolicyNumber )

因此子查询的结果(可能)对于外部查询的每一行都是不同的。

因此,两个WHERE子句的评估方式不同。

修改

可能重新编写第一个谓词

WHERE NOT EXISTS (Select 1 From tblClassCodesPlazaCommercial As t
                           Where t.PolicyNumber = cc.PolicyNumber
                             And t.ClassCode = 5151)