2014-04-23 1 views
-1

두 테이블의 데이터를 결합하여 표시하는 시나리오가 있습니다. 'DayTable'이라는 첫 번째 테이블은 일일 계획과 실제로 구성됩니다. 'MonthTable'이라는 두 번째 테이블은 월간 요금제와 실제로 구성됩니다. 지난 6 개월간의 데이터와 이번 달의 일일 데이터를 표시해야합니다. 그래서 내가 어떤 실패 후 임시 테이블을 만들 경우 때문에 임시 테이블 개념을 피하기 위해 thining하고 이제 하위 쿼리의 CTE

Output Image

처럼

Declare @startdate date = CONVERT(DATE, DATEADD(dd, -DAY(DATEADD(MONTH, 0, GETDATE())) + 1, DATEADD(MONTH, 0, GETDATE()))) 
Declare @endDate date = DATEADD(DAY, -DAY(DATEADD(MONTH, 1, GETDATE())), DATEADD(MONTH, 1, GETDATE())) 

CREATE TABLE #TEMP 
(
PlanDate NVARCHAR(100), 
[PastTrend - Plan] INT, 
[PastTrend - Actual] INT, 
[Current - Plan] INT, 
[Current - Actual] INT, 
) 

;With cte 
as 
(
    Select @startdate sDate 
    Union All 
    Select DATEADD(day,1,sDate) From cte where DATEADD(day,1,sDate) <= @endDate 
) 
INSERT INTO #TEMP 
SELECT 
REPLACE(CONVERT(CHAR(6), A.sDate, 106),' ',' - ') PlanDate 
,NULL AS [PastTrend - Plan] 
,NULL AS [PastTrend - Actual] 
,SUM(B.PlanQuantity) AS [Current - Plan] 
,SUM(B.Actual) AS [Current - Actual] 
FROM cte A 
LEFT OUTER JOIN DayTable B 
ON A.sDate = CONVERT(DATE,B.PlanDate) 
GROUP BY A.sDate 
--ORDER BY A.sDate 


SELECT 
* 

FROM 
(
SELECT 
CONVERT(CHAR(3), datename(month,PlanMonth)) + ' ' + RIGHT(CONVERT(VARCHAR(4), YEAR(PlanMonth)), 2) AS PlanDate 
,SUM(PlanQuantity) AS [PastTrend - Plan] 
,SUM(Actual) AS [PastTrend - Actual] 
,NULL AS [Current - Plan] 
,NULL AS [Current - Actual] 
FROM 
MonthTable 
WHERE CONVERT(DATE, PlanMonth) >= CONVERT(DATE, DATEADD(dd, -DAY(DATEADD(MONTH, 0, GETDATE())) + 1, DATEADD(MONTH, -6, GETDATE()))) 
group by PlanMonth 


UNION ALL 

SELECT 
PlanDate 
,[PastTrend - Plan] 
,[PastTrend - Actual] 
,[Current - Plan] 
,[Current - Actual] 
FROM 
#TEMP 

) T1 


DROP TABLE #TEMP 

내 출력이 예상 출력을 위해 나는 아래처럼 쿼리를 작성 떨어지지 않을거야. 그래서 아래와 같은 쿼리를 다시 작성하십시오.

Declare @startdate date = CONVERT(DATE, DATEADD(dd, -DAY(DATEADD(MONTH, 0, GETDATE())) + 1, DATEADD(MONTH, 0, GETDATE()))) 
Declare @endDate date = DATEADD(DAY, -DAY(DATEADD(MONTH, 1, GETDATE())), DATEADD(MONTH, 1, GETDATE())) 

;With cte 
as 
(
    Select @startdate sDate 
    Union All 
    Select DATEADD(day,1,sDate) From cte where DATEADD(day,1,sDate) <= @endDate 
) 
SELECT 
A.sDate AS OriginalDate 
,REPLACE(CONVERT(CHAR(6), A.sDate, 106),' ',' - ') PlanDate 
,NULL AS [PastTrend - Plan] 
,NULL AS [PastTrend - Actual] 
,SUM(B.PlanQuantity) AS [Current - Plan] 
,SUM(B.Actual) AS [Current - Actual] 
FROM cte A 
LEFT OUTER JOIN DayTable B 
ON A.sDate = CONVERT(DATE,B.PlanDate) 
GROUP BY A.sDate 

UNION ALL 

SELECT 
PlanMonth AS OriginalDate 
,CONVERT(CHAR(3), datename(month,PlanMonth)) + ' ' + RIGHT(CONVERT(VARCHAR(4), YEAR(PlanMonth)), 2) AS PlanDate 
,SUM(PlanQuantity) AS [PastTrend - Plan] 
,SUM(Actual) AS [PastTrend - Actual] 
,NULL AS [Current - Plan] 
,NULL AS [Current - Actual] 
FROM 
MonthTable 
WHERE CONVERT(DATE, PlanMonth) >= CONVERT(DATE, DATEADD(dd, -DAY(DATEADD(MONTH, 0, GETDATE())) + 1, DATEADD(MONTH, -6, GETDATE()))) 
group by PlanMonth 

ORDER BY OriginalDate 

하지만 여기에는 문제가 있습니다. 출력에서 나는 OriginalDate가 필요 없다. 이것을 피하는 방법. 이를 위해 선택 쿼리에 공용 출력을 래핑 할 수 있지만 어떻게 cte 오류가 있습니다. 제발 날 안내 해줘. 또한 어떤 방법이 가장 좋은지 제안하십시오.

+0

왜 임시 테이블에'IF EXISTS .... DROP'을 포함시키지 않으시겠습니까? 또한 'TRY..CATCH' 논리를 고려하여 장애가 발생할 경우 임시 테이블을 삭제할 수 있습니다. – Raj

+0

좋은 생각입니다. 하지만 임시 테이블을 피하려고합니다. 나는 어떤 방법이 좋은지 모른다. 나는 직접적인 방법이 쉽고 좋다고 생각한다. 또한 이것처럼, 나는 temp를 사용하는 다른 절차를 가지고있다. 그래서 그것을 피하기 위해 생각. 그게 다야. 임시 테이블이 더 나은 접근 방법이라면 나는 그렇게 갈 수있다. – Akhil

답변

0

나는 질의를 마쳤습니다. ACtually 난 그냥 밖으로 cte와 쿼리를 래핑. Cte는 쿼리의 맨 위에 있어야합니다. 최종 질의는

Declare @startdate date = CONVERT(DATE, DATEADD(dd, -DAY(DATEADD(MONTH, 0, GETDATE())) + 1, DATEADD(MONTH, 0, GETDATE()))) 
    Declare @endDate date = DATEADD(DAY, -DAY(DATEADD(MONTH, 1, GETDATE())), DATEADD(MONTH, 1, GETDATE())) 



;With cte 
    as 
    (
     Select @startdate sDate 
     Union All 
     Select DATEADD(day,1,sDate) From cte where DATEADD(day,1,sDate) <= @endDate 
    ) 
    SELECT 
    T1.PlanDate 
    ,T1.[PastTrend - Plan] 
    ,T1.[PastTrend - Actual] 
    ,T1.[Current - Plan] 
    ,T1.[Current - Actual] 
    FROM 
    (
    SELECT 
    A.sDate AS OriginalDate 
    ,REPLACE(CONVERT(CHAR(6), A.sDate, 106),' ',' - ') PlanDate 
    ,NULL AS [PastTrend - Plan] 
    ,NULL AS [PastTrend - Actual] 
    ,SUM(B.PlanQuantity) AS [Current - Plan] 
    ,SUM(B.Actual) AS [Current - Actual] 
    FROM cte A 
    LEFT OUTER JOIN DayTable B 
    ON A.sDate = CONVERT(DATE,B.PlanDate) 
    GROUP BY A.sDate 

    UNION ALL 

    SELECT 
    PlanMonth AS OriginalDate 
    ,CONVERT(CHAR(3), datename(month,PlanMonth)) + ' ' + RIGHT(CONVERT(VARCHAR(4), YEAR(PlanMonth)), 2) AS PlanDate 
    ,SUM(PlanQuantity) AS [PastTrend - Plan] 
    ,SUM(Actual) AS [PastTrend - Actual] 
    ,NULL AS [Current - Plan] 
    ,NULL AS [Current - Actual] 
    FROM 
    MonthTable 
    WHERE CONVERT(DATE, PlanMonth) >= CONVERT(DATE, DATEADD(dd, -DAY(DATEADD(MONTH, 0, GETDATE())) + 1, DATEADD(MONTH, -6, GETDATE()))) 
    group by PlanMonth 
    ) T1 
    ORDER BY T1.OriginalDate 

입니다.하지만 성능을 알아야합니다. 실제 실행 계획으로이 쿼리를 실행할 때 쿼리 비용 (일괄 처리 관련) : 100 % temp를 사용하는 첫 번째 방법을 실행할 때 쿼리 비용은 90 %입니다. 아무도 이것을 안내 할 수 있습니까