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

これにはさまざまなアプローチがあるかもしれません。ピボットの後ですべての合計を計算することも、最初に合計を取得してからすべての結果をピボットすることもできます。ある種の妥協点を持つことも可能です: 1 種類の合計 (行単位の合計など) を取得し、ピボットしてから、別の種類の合計を取得しますが、それはやり過ぎかもしれません。

ピボット後にすべての合計を取得する前述のアプローチの最初の方法は、非常に簡単な方法で実行できます。以下の実装で潜在的に新しいことは次のとおりです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 に答える
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 に答える