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中替换此查询,然后您将获得所需的输出
注意:很抱歉,我没有完全了解汇总功能,因此无法给出正确的解释。所以我不应该汇总每一列?顺便问一下,您对汇总的行为有何解释?我正在考虑使用多维数据集,但不是很好。对不起,目前我没有任何关于汇总行为的解释,我最终只从你的帖子中听说了汇总。我有关于透视表的知识,这有助于我找到答案