次の列を持つテーブルがあります
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
列と行の合計を取得するのに役立つ人はいますか?
これにはさまざまなアプローチがあります。ピボット後にすべての合計を計算することも、最初に合計を取得してからすべての結果をピボットすることもできます。ある種の中間的な地位を持つことも可能です。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()
部分は、Totalrowを生成します。グループ化は最初に_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でテストおよび再生できます。
注。単一の列のアンピボットは明らかに冗長であると思われたため、両方の提案でアンピボットのステップを省略しました。ただし、それだけではない場合でも、どちらかのクエリを調整するのは簡単です。
ROLLUP
を使用すると、_root_cause
_および_environment_name
_の合計を確認できます。
RNO_COLTOTAL
_-列Total
、Tsc
はピボット時に列Unkn
と重なるため、最後の列にTotal
を配置するロジック。RNO_ROWTOTAL
_-Total
、U
、W
、X
、Y
で始まる値以降の最後の行にZ
を配置するロジックは、値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
_-null値をゼロに置き換えます。クエリ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
_
[〜#〜]結果[〜#〜]
合計は別途計算する必要があると思います。合計に対してこの単純なクエリを使用します(申し訳ありませんが、 ""列のエイリアス名を指定する必要がありました):
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
私はそれをテストしていませんが、うまくいくと信じています