2016-11-17 28 views
0

PolicyNumberは複数のを持つことができます。そのため、すべての関連する列が のすべてを含むPolicyNumberをすべて削除することが目標です。少なくとも1つが削除されることが選択されている場合はClassCode'sです。 PolicyNumberWrittenPremium(WP)のcte1があり、PolicyNumberClassCodeのテーブルtblClassCodesPlazaCommercialがあります。私WHERE句イム選んで :次に同じEXISTSが異なる結果を返す理由

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

私はまだClassCodeとポリシーを持っているI select * from cte3 WHERE ClassCode =5151場合5151

enter image description here

以下全体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)) 

しかし、その後、私が@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) 

どういう違いがありますか?両方のサブクエリ自体がまったく同じ結果セットを返します。なぜ最初のケースではうまくいかないのですが、2番目(@PoliciesThatDontHaveClassCodesを宣言したとき)に動作しますか? どのようにテーブル変数を宣言せずに同じ結果を得ることができますか?外部クエリとサブクエリの間に相関がないあなたが

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

を提供最初のサンプルで

+2

が、それは同じではありません。 1つは、NOT IN(SELECT ....)を持ち、もう1つは違う条件を持っています。 2番目のクエリは実際には 'EXISTS'の結果を外部テーブルに関連づけていますが、最初の行は行が存在するかどうかを確認するだけです。存在しているので、外側テーブルのすべての結果に対して真です – Lamak

答えて

6

。したがって、サブクエリは単独で評価され、クエリで行が返されるため、WHERE EXISTS …は常にtrueです。

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

ので、サブクエリの結果はすべてのために(潜在的に)異なっている:ccはサブクエリの外側にあるため、2番目の例では

あなたは外側のクエリでサブクエリを相関、それは、t.PolicyNumber = cc.PolicyNumberが何をするかです外部クエリの単一行

したがって、2つのWHERE句の評価は異なります。

最初の述語の編集

可能なリワーク

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

、良い説明 – Lamak

+0

ああ、それを得た。ありがとう。だから私は最初のものをどのように書き直すのだろうか?出来ますか? – Oleg

+0

@Oleg「LEFT ANTI SEMI JOIN」を使用して更新された回答を見るhttp://sqlity.net/ja/1360/a-join-a-day-the-left-anti-semi-join/ – mendosi

関連する問題