サンプルテーブル
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
こちら。
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