2017-02-13 1 views
0

솔직히 말하면 며칠 동안 피벗 테이블 동작에 대해 배우려고합니다. rightnow, 나는 피벗 테이블에 행과 열의 합계를 표시 할 수 있습니다. 여기 난 당신이 볼 수열과 행의 피벗 합계가 올바른 값을 표시하지 않음

DECLARE @cols   AS NVARCHAR(MAX) 
DECLARE @colswithNoNulls AS NVARCHAR(MAX) 
DECLARE @query   AS NVARCHAR(MAX) 
DECLARE @tanggal_awal  DATE 
DECLARE @tanggal_akhir  DATE 
DECLARE @print    NVARCHAR(MAX) 
DECLARE @querycount  AS NVARCHAR(MAX) 

CREATE TABLE #datatable 
(
    product_id int, 
    product_date date, 
    product_ammount int 
) 


SET @tanggal_awal = convert(DATE,'02-01-2017') 
SET @tanggal_akhir = convert(DATE,DATEADD(dd,-1,(DATEADD(mm,1,@tanggal_awal)))) 

--SELECT DATEADD(s,-1,DATEADD(mm, DATEDIFF(m,0,GETDATE())+1,0)) 

INSERT INTO #datatable (product_id,product_date,product_ammount) VALUES 
      (1,GETDATE(),100), 
      (1,GETDATE(),900), 
      (2,DATEADD(DD,-1,GETDATE()),400), 
      (3,DATEADD(DD,4,GETDATE()),300), 
      (1,DATEADD(DD,4,GETDATE()),200), 
      (2,DATEADD(DD,2,GETDATE()),700), 
      (4,DATEADD(DD,-3,GETDATE()),1000), 
      (4,DATEADD(MM,1,GETDATE()),200), 
      (4,GETDATE(),750) 

;WITH CTE (datelist,maxdate) AS 
(
    SELECT CONVERT(INT,(MIN(DATEPART(day,@tanggal_awal)))) datelist, CONVERT(INT,MAX(DATEPART(day,product_date))) maxdate 
    FROM #datatable 
    UNION ALL 
    SELECT CONVERT(INT,(DATEPART(day,datelist))), CONVERT(INT,(DATEPART(day,@tanggal_akhir))) 
    FROM cte 
    WHERE datelist < maxdate 
) SELECT c.datelist 
    INTO #temp 
    FROM cte c 
    ORDER BY c.datelist 
    OPTION (maxrecursion 0) 

SELECT @cols = STUFF((SELECT ',' + QUOTENAME(CONVERT(int, datelist)) 
       FROM #temp 
       GROUP BY datelist 
       ORDER BY CONVERT(int, datelist) 
       FOR XML PATH(''), TYPE 
       ).value('.', 'NVARCHAR(MAX)') 
       ,1,1,'' 
       ) 


SELECT @colswithNoNulls = STUFF((SELECT ',ISNULL(' + QUOTENAME(CONVERT(int, datelist)) +',''0'') '+ QUOTENAME(CONVERT(int, datelist)) 
          FROM #temp 
          GROUP BY datelist 
          ORDER BY CONVERT(int, datelist) 
          FOR XML PATH(''), TYPE 
          ).value('.', 'NVARCHAR(MAX)') 
          ,1,1,'') 

SET @query = 
      'SELECT product_id, '+ @colswithNoNulls+', Total FROM 
      (
       select 
       ISNULL((CAST(b.product_id as nvarchar(30))), ''Total'') product_id, 
       coalesce(b.product_ammount,0) as product_ammount, 
       DATEPART(dd,(convert(CHAR(10), product_date, 120))) PivotDate, 
       SUM(product_ammount) over (partition by b.product_id) as Total 
       FROM #datatable b 
       WHERE product_date between @tanggal_awal and @tanggal_akhir 
       GROUP BY product_ammount,product_date,product_id 
       WITH ROllup 
      ) x 
      pivot 
      (
       sum(product_ammount) 
       for PivotDate in (' [email protected]+ ') 
      ) p 
      ORDER BY CASE when (product_id = ''Total'') then 1 else 0 end, product_id'   

EXECUTE sp_executesql @query ,N'@tanggal_awal DATE, @tanggal_akhir DATE', @tanggal_awal,@tanggal_akhir 

IF(OBJECT_ID('tempdb.dbo.#temp','U') IS NOT NULL) 
    BEGIN 
     TRUNCATE TABLE #temp 
     TRUNCATE TABLE #datatable 
     DROP TABLE #temp 
     DROP TABLE #datatable 
    END 
ELSE 
    BEGIN 
     SELECT '#temp is not created in this script' AS MESSAGE 
    END 

을 설정하려고하고있는 코드가, 결과가 화면에 표시됩니다. 그러나 오른쪽 하단의 총 값은이 그림에서와 같이 정확한 총 값이 두 배가 된 것처럼 이상합니다. enter image description here 이 문제를 해결하는 방법 btw? 그것은 나를 위해 약간 혼란 스럽기 때문에. 도와 주셔서 감사합니다.

답변

1

일반적으로 롤업 기능을 완전히 인식하지 못했습니다. PIVOT 쿼리에서. 일부 빈 행 (기본적으로 "롤업"옵션에서 소계 행), 그래서 예상대로 결과를 얻기 위해 문을 그룹에 의해 수정 된오고 발견했다.

   select 
      ISNULL((CAST(b.product_id as nvarchar(30))), 'Total') product_id, 
      coalesce(b.product_ammount,0) as product_ammount, 
      DATEPART(dd,(convert(CHAR(10), product_date, 120))) PivotDate, 
      SUM(product_ammount) over (partition by b.product_id) as Total 
      FROM #datatable b 
      WHERE product_date between @tanggal_awal and @tanggal_akhir 
      GROUP BY product_ammount,product_date,ROllup(product_id) 

PIVOT에서이 쿼리를 바꿔서 원하는 출력을 얻습니다.

참고 : 죄송합니다. 롤업 기능을 완전히 알지 못해서 올바른 설명을 드릴 수 없습니다.

+0

그래서 모든 단일 열을 롤업하지 않아야합니까? btw 롤업의 동작에 대한 설명이 있습니까? 나는 큐브를 사용하는 것에 대해 생각하고 있지만 그다지 훌륭하지는 않습니다. –

+0

죄송합니다. 현재 롤업의 동작에 대한 설명이 없으므로 결국 귀하의 게시물에서만 롤업에 관해 들었습니다. 나는 대답을 찾는데 도움이되는 PIVOT 테이블에 대한 지식을 가지고있다. –