Sql server 为什么相同的存在会返回不同的结果

Sql server 为什么相同的存在会返回不同的结果,sql-server,tsql,exists,notin,Sql Server,Tsql,Exists,Notin,每个PolicyNumber可以有多个类代码。因此,目标是消除所有相关列的整个PolicyNumber 如果至少有一个类代码被删除,则包含所有类代码。 我有带有PolicyNumber和WrittenPremiumWP的cte1,还有带有PolicyNumber和ClassCode的tblClassCodesPlazaCommercial表。 在我的WHERE子句中,我选择: WHERE EXISTS ( SELECT DISTINCT Po

每个PolicyNumber可以有多个类代码。因此,目标是消除所有相关列的整个PolicyNumber 如果至少有一个类代码被删除,则包含所有类代码。 我有带有PolicyNumber和WrittenPremiumWP的cte1,还有带有PolicyNumber和ClassCode的tblClassCodesPlazaCommercial表。 在我的WHERE子句中,我选择:

WHERE       EXISTS (
                    SELECT  DISTINCT PolicyNumber 
                    FROM    tblClassCodesPlazaCommercial 
                    WHERE   PolicyNumber NOT IN (SELECT  PolicyNumber FROM tblClassCodesPlazaCommercial WHERE  ClassCode =5151)
                    )
然后,如果我从cte3中选择*,其中ClassCode=5151,我仍然有ClassCode为5151的策略

下面是整个select语句:

 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))
但是,如果我用PolicyNumber声明@policiesthattonthaveClassCodes表,而PolicyNumber没有类代码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 )
有什么区别?这两个子查询本身返回完全相同的结果集。为什么在第一种情况下它不起作用,但在第二种情况下,当我声明@policiesthattonthaveClassCodes时,它起作用了?
如何在不声明任何表变量的情况下获得相同的结果?

在您提供的第一个示例中

WHERE EXISTS (SELECT  DISTINCT PolicyNumber 
                FROM    tblClassCodesPlazaCommercial 
                WHERE   PolicyNumber NOT IN (SELECT  PolicyNumber 
                                               FROM tblClassCodesPlazaCommercial 
                                               WHERE  ClassCode =5151))
外部查询和子查询之间没有相关性。因此,我们单独评估子查询,因为查询返回一行,所以WHERE EXISTS…始终为true

在第二个示例中,您将子查询与外部查询关联起来,这就是t.PolicyNumber=cc.PolicyNumber所做的,因为cc在子查询之外:

WHERE EXISTS (SELECT * FROM @PoliciesThatDontHaveClassCodes t  
               WHERE t.PolicyNumber=cc.PolicyNumber )
因此,对于外部查询的每一行,子查询的结果都可能不同

因此,这两个WHERE子句的评价不同

编辑

第一个谓词的可能重写


但这不一样。在其中一个示例中,您有一个不在选择中的。。。。另一个有不同的情况。第二个查询实际上是将EXISTS的结果与外部表关联起来,第一个查询只是查看是否存在任何行……因为它确实存在,所以对于外部表中的每个结果都是正确的哦,明白了。谢谢那么我如何重写第一个呢?有可能吗?@Oleg使用左反半联接查看更新的答案@Oleg如果此答案解决了您的问题,请接受。它确实解决了。对不起。谢谢你的解释!!
WHERE NOT EXISTS (Select 1 From tblClassCodesPlazaCommercial As t
                           Where t.PolicyNumber = cc.PolicyNumber
                             And t.ClassCode = 5151)