Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/unit-testing/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server 列和行的透视总计未显示正确的值_Sql Server_Sql Server 2014 - Fatal编程技术网

Sql server 列和行的透视总计未显示正确的值

Sql server 列和行的透视总计未显示正确的值,sql-server,sql-server-2014,Sql Server,Sql Server 2014,老实说,几天来,我一直在努力学习透视表的行为。现在,我能够在透视表中显示行和列的总和。下面是我试图设置的代码 DECLARE @cols AS NVARCHAR(MAX) DECLARE @colswithNoNulls AS NVARCHAR(MAX) DECLARE @query AS NVARCHAR(MAX) DECLARE @tanggal_awal DATE DECLARE @tanggal_akhir DATE DEC

老实说,几天来,我一直在努力学习透视表的行为。现在,我能够在透视表中显示行和列的总和。下面是我试图设置的代码

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 (' +@cols+ ')
            ) 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
如您所见,结果显示在显示屏上。然而,最右下方的总值很奇怪,因为它就像是这张图片中精确总值的两倍:
顺便说一句,如何解决这个问题?因为这让我有点困惑。感谢您的帮助:

一般来说,我并不完全了解汇总功能。从您的透视查询。我发现一些空行基本上来自于使用Rollup选项的小计行,所以我稍微修改了GROUPBY语句以达到预期的结果

                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中替换此查询,然后您将获得所需的输出


注意:很抱歉,我没有完全了解汇总功能,因此无法给出正确的解释。

所以我不应该汇总每一列?顺便问一下,您对汇总的行为有何解释?我正在考虑使用多维数据集,但不是很好。对不起,目前我没有任何关于汇总行为的解释,我最终只从你的帖子中听说了汇总。我有关于透视表的知识,这有助于我找到答案