2016-11-16 6 views
0

여러 테이블을 여러 테이블에 조인하고 있습니다.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)) 

필자의 경우 쿼리 성능을 향상시키는 다른 방법이 있습니까?

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를 들어, 당신이이 방법을 쓸 수 있다고 생각, 그것은

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

하하, 나는 그것이 도움이되어 기쁩니다. 즐거웠 어 :) –