12

我有一个包含以下列的表格

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

任何人都可以帮助获取列和行的总数吗?

4

4 回答 4

19

对此可能有多种方法。您可以在透视后计算所有总计,也可以先获取总计,然后透视所有结果。也有可能有一种中间立场:获取一种总数(例如,按行计算的总数),枢轴,然后获取另一种,尽管这可能有点过头了。

提到的第一种方法,在枢轴之后获取所有总数,可以以非常简单的方式完成,并且在以下实现中对您来说唯一可能是新的可能是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()部分会为您生成总计。分组首先由 完成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 进行测试和使用:

笔记。我在这两个建议中都省略了反透视步骤,因为反透视单个列似乎显然是多余的。但是,如果还有更多内容,则调整其中一个查询应该很容易。

于 2013-06-17T07:38:20.143 回答
3

您可以找到 Total for root_causeenvironment_nameusing ROLLUP

  • RNO_COLTOTAL- 放置Total在最后一列的逻辑,因为列TscUnknTotal在旋转时与列重叠,因为它按字母顺序排列。
  • RNO_ROWTOTAL- 逻辑放置Total在最后一行,因为以U, W, X,开头YZ值可以与值重叠Total,因为它按字母顺序排列。
  • SUM(VALUE)- 可以定义我们可以使用的聚合函数ROLLUP

查询 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- 用零替换空值。

查询 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

结果

在此处输入图像描述

于 2014-12-01T09:23:11.513 回答
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 

我没有测试过,但相信它会工作

于 2013-06-17T05:28:46.613 回答
0

您还可以将不带总计的选择数据透视表放在临时表中,然后使用新选择添加总计:

SELECT  environment_name=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 #temp
    GROUP BY ROLLUP(environment_name)
于 2022-01-26T17:30:32.623 回答