2016-11-16 5 views
0

多対多の関係で2つのテーブルを結合しています。NOT INを使用するとクエリのパフォーマンスが向上する方法

enter image description here 最終結果では、各PolicyNumberに複数のClassCodeがあります。 は、以下のようになります。

enter image description here

今、私はSSRSで@ClassCodeパラメータが選びだしされている場合PaidLossesで全体PolicyNumberを除外する必要があります。 したがって、NOT INを使用してPolicyNumberをなくすと、永遠に回転します。

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 
      AND cc.PolicyNumber IN (SELECT PolicyNumber FROM tblClassCodesPlazaCommercial WHERE ClassCode NOT IN (@ClassCode)) 

私の場合、他の方法でクエリのパフォーマンスを改善できますか?

全体のクエリは以下の通りです:CTE3については

DECLARE @ClassCode int = 5151 
;with cte1 
as 
(
SELECT  QuoteID, 
      CONVERT(VARCHAR(10),TransactionEffectiveDate,101) as TransactionEffectiveDate, 
      PolicyNumber, 
      SUM(WrittenPremium) as WP       
FROM  PlazaInsuranceWPDataSet  

WHERE  State IN ('CA','NV','AZ') 
GROUP BY  
      PolicyNumber, 
      QuoteID, 
      TransactionEffectiveDate  
), 
cte3 
as 
(
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 
      AND cc.PolicyNumber IN (SELECT PolicyNumber FROM tblClassCodesPlazaCommercial WHERE ClassCode NOT IN (@ClassCode)) 
) 
select 
     c.YearNum, 
     c.MonthNum, 
     SUM(WP) as WP   
from cte3 RIGHT JOIN tblCalendar c ON c.YearNum=YEAR(TransactionEffectiveDate) AND c.MonthNum=MONTH(TransactionEffectiveDate) 
WHERE c.YearNum <>2017 
GROUP BY  
      c.YearNum, 
      c.MonthNum 
ORDER BY c.YearNum desc, 
      c.MonthNum 
+0

申し訳ありませんが、あなたは、 'NOTを使用しています単一の整数値をテストするために '<>'の代わりに 'IN'を使用します:' WHERE ClassCode NOT IN(@ClassCode) '?他の 'IN'相関サブクエリに対して' EXISTS'を調べましたか?または「OUTER JOIN」? – HABO

+0

<を試しました。それでも、永遠に取る。 – Oleg

+0

EXISTSも試しました。それでも同じ – Oleg

答えて

1

、私はあなたがこの方法を書くことができると思うし、それがパフォーマンスの向上に役立つかもしれない

cte3 
as 
(
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 cc.ClassCode NOT IN (@ClassCode)) 
    ) 
+0

したがって、ClassCodeだけでなく、@ClassCodeが選択されている場合はPolicyNumber全体を削除することが目標でした。私はすでにEXISTS、NOT IN、NOT EXISTS、LEFT ANTI SEMI JOINを使って3日間戦っていました。パフォーマンスは永遠に続いていました。そして、あなたは私の一日を作っただけではありませんでした - あなたは私の一週間を過ごしました!!!!!私はこのシンプルな「WHERE」節がすべてがうまくいって、とても速くなったと信じていません。 ありがとうございます! – Oleg

+0

笑、私はそれが助けてうれしいです。楽しむ :) –

関連する問題