我有一组输出数据透视表的查询。是否可以获得数据透视表的行和/或列小计?
我选择的表格是这样的
Site FormID Present
Site 1 Form A Yes
Site 1 Form B Yes
Site 1 Form D Yes
等等......
我的数据透视表查询是
SELECT *
FROM (SELECT Site, COUNT(FormID) AS NumberOfForms,FormID
FROM @CRFCount WHERE Present='Yes'
GROUP BY Site, FormID) d
PIVOT
(SUM(NumberOfForms)
FOR [Site] IN ([Site 1], [Site 2], [Site 3])
) AS p;
但我真的希望它导致这一点(当然这对我来说并不完全)
FormID Site 1 Site 2 Site 3 Total
Form A 8 8 15 31
Form B 14 4 NULL 18
Form C 14 NULL NULL 14
Form D 15 3 16 34
Form E 12 4 NULL 16
Form F 14 5 5 24
Form G 14 8 6 28
Form H 22 10 15 47
Form I 15 10 16 41
Form J 15 5 16 36
Total 143 57 89 289
感谢您的协助!
-Don
答案 0 :(得分:7)
;WITH C as
(
SELECT FormID,
[Site 1],
[Site 2],
[Site 3],
(SELECT SUM(S)
FROM (VALUES([Site 1]),
([Site 2]),
([Site 3])) AS T(S)) as Total
FROM (SELECT Site, COUNT(FormID) AS NumberOfForms,FormID
FROM @CRFCount WHERE Present='Yes'
GROUP BY Site, FormID) d
PIVOT
(SUM(NumberOfForms)
FOR [Site] IN ([Site 1], [Site 2], [Site 3])
) AS p
)
SELECT *
FROM
(
SELECT FormID,
[Site 1],
[Site 2],
[Site 3],
Total
FROM C
UNION ALL
SELECT 'Total',
SUM([Site 1]),
SUM([Site 2]),
SUM([Site 3]),
SUM(Total)
FROM C
) AS T
ORDER BY CASE WHEN FormID = 'Total' THEN 1 END
注意:如果您使用的是SQL Server 2005,则需要更改此内容:
(SELECT SUM(S)
FROM (VALUES([Site 1]),
([Site 2]),
([Site 3])) AS T(S)) as Total
到
(SELECT SUM(S)
FROM (SELECT [Site 1] UNION ALL
SELECT [Site 2] UNION ALL
SELECT [Site 3]) AS T(S)) as Total
试试SE Data
答案 1 :(得分:2)
试试这个(未经测试):
SELECT *
FROM
(
SELECT
Site = case when grouping(Site)=1 then 'All' else Site end,
FormID = case when grouping(FormID)=1 then 'All' else cast(FormID as varchar(100)) end,
measure = count(NumberOfForms)
FROM @CRFCount
-- chose below
GROUP BY Site, FormID with cube --(ms sql 2005)
--group by grouping sets(Site, FormID, (Site, FormID), ()) --(ms sql 2008)
) AS BOM
PIVOT (max(measure) FOR [Site] IN ([Site 1], [Site 2], [Site 3], [All]))
as pv
答案 2 :(得分:0)
样本表
SELECT * INTO #TEMP
FROM
(
SELECT 'Site 1' [Site], 'Form A' [FormID], 'Yes' Present
UNION ALL
SELECT 'Site 1', 'Form B', 'Yes'
UNION ALL
SELECT 'Site 1', 'Form C', 'Yes'
UNION ALL
SELECT 'Site 1', 'Form B', 'NO'
UNION ALL
SELECT 'Site 1', 'Form C', 'NO'
UNION ALL
SELECT 'Site 2', 'Form A', 'Yes'
UNION ALL
SELECT 'Site 2', 'Form A', 'Yes'
UNION ALL
SELECT 'Site 2', 'Form B', 'Yes'
UNION ALL
SELECT 'Site 2', 'Form B', 'NO'
UNION ALL
SELECT 'Site 2', 'Form C', 'Yes'
UNION ALL
SELECT 'Site 3', 'Form B', 'Yes'
UNION ALL
SELECT 'Site 3', 'Form A', 'Yes'
UNION ALL
SELECT 'Site 3', 'Form C', 'Yes'
UNION ALL
SELECT 'Site 3', 'Form A', 'Yes'
)TAB
<强> 1。行和列总计
-- Get the columns for dynamic pivot
DECLARE @cols NVARCHAR (MAX)
SELECT @cols = COALESCE (@cols + ',[' + [Site] + ']', '[' + [Site] + ']')
FROM (SELECT DISTINCT [Site] FROM #TEMP WHERE Present='YES') PV
ORDER BY [Site]
-- Since we need Total in last column, we append it at last
SELECT @cols += ',[Total]'
您可以使用CUBE
获取旋转时的行和列总数。有关CUBE
here的更多信息。
DECLARE @query NVARCHAR(MAX)
SET @query = 'SELECT FORMID,' + @cols + ' FROM
(
SELECT
ISNULL([SITE],''Total'')[SITE],
SUM(CNT)CNT ,
ISNULL(FORMID,''Total'')FORMID
FROM
(
SELECT DISTINCT [SITE],FORMID,
COUNT(FORMID) OVER(PARTITION BY [SITE],FORMID) CNT
FROM #TEMP
WHERE PRESENT=''YES''
)TAB
GROUP BY [SITE],FORMID
WITH CUBE
) x
PIVOT
(
MIN(CNT)
FOR [SITE] IN (' + @cols + ')
) p
ORDER BY CASE WHEN (FORMID=''Total'') THEN 1 ELSE 0 END,FORMID'
EXEC SP_EXECUTESQL @query
<强> 2。仅限行
您可以使用ROLLUP
获取行总数。
-- Get the columns for dynamic pivot
DECLARE @cols NVARCHAR (MAX)
SELECT @cols = COALESCE (@cols + ',[' + [Site] + ']', '[' + [Site] + ']')
FROM (SELECT DISTINCT [Site] FROM #TEMP WHERE Present='YES') PV
ORDER BY [Site]
DECLARE @query NVARCHAR(MAX)
SET @query = 'SELECT FORMID,' + @cols + ' FROM
(
SELECT
ISNULL([SITE],''Total'')[SITE],
SUM(CNT)CNT ,
ISNULL(FORMID,''Total'')FORMID
FROM
(
SELECT DISTINCT [SITE],FORMID,
COUNT(FORMID) OVER(PARTITION BY [SITE],FORMID) CNT
FROM #TEMP
WHERE PRESENT=''YES''
)TAB
GROUP BY [SITE],FORMID
WITH ROLLUP
) x
PIVOT
(
MIN(CNT)
FOR [SITE] IN (' + @cols + ')
) p
ORDER BY CASE WHEN (FORMID=''Total'') THEN 1 ELSE 0 END,FORMID'
EXEC SP_EXECUTESQL @query
第3。仅列总计
将GROUP BY [SITE],FORMID
更改为GROUP BY FORMID,[SITE]
-- Get the columns for dynamic pivot
DECLARE @cols NVARCHAR (MAX)
SELECT @cols = COALESCE (@cols + ',[' + [Site] + ']', '[' + [Site] + ']')
FROM (SELECT DISTINCT [Site] FROM #TEMP WHERE Present='YES') PV
ORDER BY [Site]
--Since we need Total in last column, we append it at last
SELECT @cols += ',[Total]'
DECLARE @query NVARCHAR(MAX)
SET @query = 'SELECT FORMID,' + @cols + ' FROM
(
SELECT
ISNULL([SITE],''Total'')[SITE],
SUM(CNT)CNT ,
ISNULL(FORMID,''Total'')FORMID
FROM
(
SELECT DISTINCT [SITE],FORMID,
COUNT(FORMID) OVER(PARTITION BY [SITE],FORMID) CNT
FROM #TEMP
WHERE PRESENT=''YES''
)TAB
GROUP BY FORMID,[SITE]
WITH ROLLUP
) x
PIVOT
(
MIN(CNT)
FOR [SITE] IN (' + @cols + ')
) p
WHERE FORMID <> ''Total''
ORDER BY FORMID'
EXEC SP_EXECUTESQL @query
现在,如果要将null替换为零,则可以在动态数据透视之前使用以下代码。
DECLARE @NulltoZeroCols NVARCHAR (MAX)
SELECT @NullToZeroCols = SUBSTRING((SELECT ',ISNULL(['+[Site]+'],0) AS ['+[Site]+']'
FROM (SELECT DISTINCT [Site] FROM #TEMP)TAB
ORDER BY [Site] FOR XML PATH('')),2,8000)
SELECT @NullToZeroCols += ',ISNULL([Total],0) AS [Total]'
在大多数动态数据透视查询中,将@cols
变量替换为@NullToZeroCols