我有一个包含以下列的表
defect_id, developer_name, status, summary, root_cause,
Secondary_RC, description, Comments, environment_name
专栏root_cause
包含Enviro,Requi,Dev,TSc,TD,Unkn作为其值和
列environment_name具有QA1,QA2,QA3
我需要以下面的格式准备一份报告
Enviro Requi Dev TSc TD Unkn Total
QA1 9 1 14 17 2 3 46
QA2 8 1 14 0 5 1 29
QA3 1 1 7 0 0 1 10
Total 18 3 35 17 7 5 85
我已准备好报告
Enviro Requi Dev TSc TD Unkn
QA1 9 1 14 17 2 3
QA2 8 1 14 0 5 1
QA3 1 1 7 0 0 1
我使用以下查询来获得上述结果
select *
from
(
select environment_name as " ", value
from test1
unpivot
(
value
for col in (root_cause)
) unp
) src
pivot
(
count(value)
for value in ([Enviro] , [Requi] , [Dev] , [Tsc], [TD] , [Unkn])
) piv
任何人都可以帮助获取列和行的总数吗?
答案 0 :(得分:17)
可能有各种方法。您可以计算枢轴后的所有总计,或者您可以先获得总计,然后转动所有结果。也有可能有一种中间立场:获得一种总数(例如行式),枢轴,然后得到另一种,尽管这可能是过度的。
上面提到的第一种方法,在枢轴之后得到所有总数,可以非常直接的方式完成,并且在下面的实现中唯一可能是新的东西可能是GROUP BY ROLLUP()
:
SELECT
[ ] = ISNULL(environment_name, 'Total'),
[Enviro] = SUM([Enviro]),
[Requi] = SUM([Requi]),
[Dev] = SUM([Dev]),
[Tsc] = SUM([Tsc]),
[TD] = SUM([TD]),
[Unkn] = SUM([Unkn]),
Total = SUM([Enviro] + [Requi] + [Dev] + [Tsc] + [TD] + [Unkn])
FROM (
SELECT environment_name, root_cause
FROM test1
) s
PIVOT (
COUNT(root_cause)
FOR root_cause IN ([Enviro], [Requi], [Dev], [Tsc], [TD], [Unkn])
) p
GROUP BY
ROLLUP(environment_name)
;
基本上,GROUP BY ROLLUP()
部分会为您生成Total 行。分组首先由environment_name
完成,然后添加总计行。
要做相反的事情,即在转动之前得到总数,你可以像这样使用GROUP BY CUBE()
:
SELECT
[ ] = environment_name,
[Enviro] = ISNULL([Enviro], 0),
[Requi] = ISNULL([Requi] , 0),
[Dev] = ISNULL([Dev] , 0),
[Tsc] = ISNULL([Tsc] , 0),
[TD] = ISNULL([TD] , 0),
[Unkn] = ISNULL([Unkn] , 0),
Total = ISNULL(Total , 0)
FROM (
SELECT
environment_name = ISNULL(environment_name, 'Total'),
root_cause = ISNULL(root_cause, 'Total'),
cnt = COUNT(*)
FROM test1
WHERE root_cause IS NOT NULL
GROUP BY
CUBE(environment_name, root_cause)
) s
PIVOT (
SUM(cnt)
FOR root_cause IN ([Enviro], [Requi], [Dev], [Tsc], [TD], [Unkn], Total)
) p
;
这两种方法都可以在SQL Fiddle中进行测试和播放:
注意。我已经省略了两个建议中的隐蔽步骤,因为对单个列进行拆分似乎显然是多余的。但是,如果有更多内容,调整其中一个查询应该很容易。
答案 1 :(得分:2)
您可以使用root_cause
找到environment_name
和ROLLUP
的总计。
RNO_COLTOTAL
- 将Total
放在最后一列的逻辑,因为列Tsc
,Unkn
在旋转时会与列Total
重叠,因为它的排序按字母顺序。RNO_ROWTOTAL
- 将Total
放在最后一行的逻辑,因为值以U
,W
,X
,Y
开头,Z
可以重叠值Total
,因为它按字母顺序排序。SUM(VALUE)
- 可以定义我们可以使用ROLLUP
的聚合函数。 QUERY 1
SELECT CASE WHEN root_cause IS NULL THEN 1 ELSE 0 END RNO_COLTOTAL,
CASE WHEN environment_name IS NULL THEN 1 ELSE 0 END RNO_ROWTOTAL,
ISNULL(environment_name,'Total')environment_name,
ISNULL(root_cause,'Total')root_cause,
SUM(VALUE) VALUE
INTO #NEWTABLE
FROM
(
-- Find the count for environment_name,root_cause
SELECT DISTINCT *,COUNT(*) OVER(PARTITION BY environment_name,root_cause)VALUE
FROM #TEMP
)TAB
GROUP BY root_cause,environment_name
WITH CUBE
使用CUBE
时,我们将获得以下逻辑
我们声明了用于旋转的变量。
@cols
- 用于旋转的列值。@NulltoZeroCols
- 将空值替换为零。QUERY 2
DECLARE @cols NVARCHAR (MAX)
SELECT @cols = COALESCE (@cols + ',[' + root_cause + ']',
'[' + root_cause + ']')
FROM (SELECT DISTINCT RNO_COLTOTAL,root_cause FROM #NEWTABLE) PV
ORDER BY RNO_COLTOTAL,root_cause
DECLARE @NulltoZeroCols NVARCHAR (MAX)
SET @NullToZeroCols = SUBSTRING((SELECT ',ISNULL(['+root_cause+'],0) AS ['+root_cause+']'
FROM(SELECT DISTINCT RNO_COLTOTAL,root_cause FROM #NEWTABLE GROUP BY RNO_COLTOTAL,root_cause)TAB
ORDER BY RNO_COLTOTAL FOR XML PATH('')),2,8000)
现在动态转动
DECLARE @query NVARCHAR(MAX)
SET @query = 'SELECT environment_name,'+ @NulltoZeroCols +' FROM
(
SELECT RNO_ROWTOTAL,environment_name,root_cause,VALUE
FROM #NEWTABLE
) x
PIVOT
(
MIN(VALUE)
FOR [root_cause] IN (' + @cols + ')
) p
ORDER BY RNO_ROWTOTAL,environment_name;'
EXEC SP_EXECUTESQL @query
<强> RESULT 强>
答案 2 :(得分:1)
我认为您需要单独计算总计。使用这个简单的查询总计(抱歉,必须为您的“”列提供别名):
select environment_name as en,
count (*) AS Total
FROM test1
WHERE value in ('Enviro', 'Requi', 'Dev', 'Tsc', 'TD', 'Unkn')
GROUP BY environment_name
您可以轻松地将两个查询一起加入以获取所需的报告:
SELECT * FROM
(select *
from
(
select environment_name as en, value
from test1
unpivot
(
value
for col in (root_cause)
) unp
) src
pivot
(
count(value)
for value in ([Enviro] , [Requi] , [Dev] , [Tsc], [TD] , [Unkn])
) piv
) AS a
INNER JOIN
( select environment_name as en,
count (*) AS Total
FROM test1
WHERE value in ('Enviro', 'Requi', 'Dev', 'Tsc', 'TD', 'Unkn')
GROUP BY environment_name
) AS b ON a.en = b.en
UNION ALL
SELECT * FROM
(select *
from
(
select 'Total' as en, value
from test1
unpivot
(
value
for col in (root_cause)
) unp
) src
pivot
(
count(value)
for value in ([Enviro] , [Requi] , [Dev] , [Tsc], [TD] , [Unkn])
) piv
) AS a
INNER JOIN
( select 'Total' as en,
count (*) AS Total
FROM test1
WHERE value in ('Enviro', 'Requi', 'Dev', 'Tsc', 'TD', 'Unkn')
) AS b
我没有测试过,但相信它会起作用