本文章說明使用PIVOT + UNION ALL來將彙總資料行一列一列的加上去
有朋友在問想要達到上圖的功能,要如何做呢?
一看到要將某欄位的資料以多欄來呈現,就會想到使用 PIVOT 。
PIVOT 一次只能用一個彙總資料行,那如果要多行的話,可以參考「PIVOT使用多個彙總資料行(Multiple Aggregates)」。
而這次的需求是要那些彙總資料行一列一列的加上去,這時,筆者想到的就是使用 UNION ALL 來加入,如下,
--先建立測試的Table & 資料
USE tempdb
go
--drop table [dbo].[Sheet2]
CREATE TABLE [dbo].[Sheet2](
[DistrictName] [nvarchar](255) NULL,
[DistrictID] [nvarchar](255) NULL,
[StyleID] [nvarchar](255) NULL,
[區間系列數量] [float] NULL,
[區間系列銷售金額] [float] NULL,
[去年系列數量] [float] NULL,
[去年系列銷售金額] [float] NULL,
[前年系列數量] [float] NULL,
[前年系列銷售金額] [float] NULL
) ON [PRIMARY]
GO
INSERT [dbo].[Sheet2] ([DistrictName], [DistrictID], [StyleID], [區間系列數量], [區間系列銷售金額], [去年系列數量], [去年系列銷售金額], [前年系列數量], [前年系列銷售金額]) VALUES (N'北區', N'北區', N'傳統', 0, 0, 1, 13178, 0, 0)
GO
INSERT [dbo].[Sheet2] ([DistrictName], [DistrictID], [StyleID], [區間系列數量], [區間系列銷售金額], [去年系列數量], [去年系列銷售金額], [前年系列數量], [前年系列銷售金額]) VALUES (N'北區', N'北區', N'休閒', 0, 0, 1, 13479, 0, 0)
GO
INSERT [dbo].[Sheet2] ([DistrictName], [DistrictID], [StyleID], [區間系列數量], [區間系列銷售金額], [去年系列數量], [去年系列銷售金額], [前年系列數量], [前年系列銷售金額]) VALUES (N'中區', N'中區', N'傳統', 12, 70168460.73, 12, 76756774.01, 12, 76466446.76)
GO
INSERT [dbo].[Sheet2] ([DistrictName], [DistrictID], [StyleID], [區間系列數量], [區間系列銷售金額], [去年系列數量], [去年系列銷售金額], [前年系列數量], [前年系列銷售金額]) VALUES (N'中區', N'中區', N'現代', 9, 10335226.26, 9, 33287173.21, 8, 13748774.32)
GO
INSERT [dbo].[Sheet2] ([DistrictName], [DistrictID], [StyleID], [區間系列數量], [區間系列銷售金額], [去年系列數量], [去年系列銷售金額], [前年系列數量], [前年系列銷售金額]) VALUES (N'中區', N'中區', N'休閒', 9, 22249265.97, 9, 44831288.9, 9, 31917989.87)
GO
INSERT [dbo].[Sheet2] ([DistrictName], [DistrictID], [StyleID], [區間系列數量], [區間系列銷售金額], [去年系列數量], [去年系列銷售金額], [前年系列數量], [前年系列銷售金額]) VALUES (N'南區', N'南區', N'傳統', 12, 34738905.12, 12, 31058522.49, 12, 26617728.18)
GO
INSERT [dbo].[Sheet2] ([DistrictName], [DistrictID], [StyleID], [區間系列數量], [區間系列銷售金額], [去年系列數量], [去年系列銷售金額], [前年系列數量], [前年系列銷售金額]) VALUES (N'南區', N'南區', N'現代', 9, 5728309.98, 9, 6696724.21, 8, 6097510.16)
GO
INSERT [dbo].[Sheet2] ([DistrictName], [DistrictID], [StyleID], [區間系列數量], [區間系列銷售金額], [去年系列數量], [去年系列銷售金額], [前年系列數量], [前年系列銷售金額]) VALUES (N'南區', N'南區', N'休閒', 9, 10829249.09, 9, 10446786.25, 9, 12767264.61)
GO
SELECT * FROM Sheet2;
--先取出欄位名稱(使用動態的方式來串出欄位名稱)
DECLARE @qty_columns NVARCHAR(MAX)
SELECT @qty_columns = COALESCE(@qty_columns + ',[' + RTRIM(T.DS)
+ ']', '[' + RTRIM(T.DS) + ']')
FROM ( SELECT DISTINCT DistrictName + '-' + StyleID AS DS
FROM dbo.Sheet2
) T
PRINT @qty_columns
--將欄位名稱串接進去
EXEC(N'SELECT T2.*
FROM
(
SELECT *
FROM ( SELECT DistrictName + ''-'' + StyleID AS GP
, [區間系列數量]
, N''[區間系列數量]'' as [區域/風格]
FROM dbo.Sheet2
) AS SourceTable PIVOT
( SUM([區間系列數量]) FOR GP IN (' + @qty_columns + ' ) )
AS p1
UNION ALL
SELECT *
FROM ( SELECT DistrictName + ''-'' + StyleID AS GP
, [區間系列銷售金額]
, N''[區間系列銷售金額]'' as [區域/風格]
FROM dbo.Sheet2
) AS SourceTable PIVOT
( SUM([區間系列銷售金額]) FOR GP IN (' + @qty_columns + ' ) )
AS p2
UNION ALL
SELECT *
FROM ( SELECT DistrictName + ''-'' + StyleID AS GP
, [去年系列數量]
, N''[去年系列數量]'' as [區域/風格]
FROM dbo.Sheet2
) AS SourceTable PIVOT
( SUM([去年系列數量]) FOR GP IN (' + @qty_columns + ' ) )
AS p3
UNION ALL
SELECT *
FROM ( SELECT DistrictName + ''-'' + StyleID AS GP
, [去年系列銷售金額]
, N''[去年系列銷售金額]'' as [區域/風格]
FROM dbo.Sheet2
) AS SourceTable PIVOT
( SUM([去年系列銷售金額]) FOR GP IN (' + @qty_columns + ' ) )
AS p4
UNION ALL
SELECT *
FROM ( SELECT DistrictName + ''-'' + StyleID AS GP
, [前年系列數量]
, N''[前年系列數量]'' as [區域/風格]
FROM dbo.Sheet2
) AS SourceTable PIVOT
( SUM([前年系列數量]) FOR GP IN (' + @qty_columns + ' ) )
AS p5
UNION ALL
SELECT *
FROM ( SELECT DistrictName + ''-'' + StyleID AS GP
, [前年系列銷售金額]
, N''[前年系列銷售金額]'' as [區域/風格]
FROM dbo.Sheet2
) AS SourceTable PIVOT
( SUM([前年系列銷售金額]) FOR GP IN (' + @qty_columns + ' ) )
AS p6 ) T2
');
這樣看起來似乎沒有依Sort來排序,所以可以建立相關的Sort Table,如下,
--建立排序用的Table
--區
CREATE TABLE District
(
[DistrictName] [nvarchar](255) NULL,
[Sort_Order] INT,
);
go
INSERT INTO District(DistrictName, Sort_Order) VALUES(N'北區', 10);
INSERT INTO District(DistrictName, Sort_Order) VALUES(N'中區', 20);
INSERT INTO District(DistrictName, Sort_Order) VALUES(N'南區', 30);
--風格
CREATE TABLE Style
(
[StyleID] [nvarchar](255) NULL,
[Sort_Order] INT,
);
GO
INSERT INTO Style([StyleID], Sort_Order) VALUES(N'現代', 10);
INSERT INTO Style([StyleID], Sort_Order) VALUES(N'傳統', 20);
INSERT INTO Style([StyleID], Sort_Order) VALUES(N'休閒', 30);
GO
--SELECT TOP 99 A.DistrictName + '-' + B.StyleID
--FROM District A, Style B
--ORDER BY A.Sort_Order, B.Sort_Order;
--先取出欄位名稱(使用動態的方式來串出欄位名稱)
DECLARE @qty_columns NVARCHAR(MAX)
SELECT @qty_columns = COALESCE(@qty_columns + ',[' + RTRIM(T.DS)
+ ']', '[' + RTRIM(T.DS) + ']')
FROM ( SELECT TOP(99) A.DistrictName + '-' + B.StyleID AS DS
FROM District A, Style B
ORDER BY A.Sort_Order, B.Sort_Order
) T
PRINT @qty_columns
--將欄位名稱串接進去
EXEC(N'SELECT T2.*
FROM
(
SELECT *
FROM ( SELECT DistrictName + ''-'' + StyleID AS GP
, [區間系列數量]
, N''[區間系列數量]'' as [區域/風格]
FROM dbo.Sheet2
) AS SourceTable PIVOT
( SUM([區間系列數量]) FOR GP IN (' + @qty_columns + ' ) )
AS p1
UNION ALL
SELECT *
FROM ( SELECT DistrictName + ''-'' + StyleID AS GP
, [區間系列銷售金額]
, N''[區間系列銷售金額]'' as [區域/風格]
FROM dbo.Sheet2
) AS SourceTable PIVOT
( SUM([區間系列銷售金額]) FOR GP IN (' + @qty_columns + ' ) )
AS p2
UNION ALL
SELECT *
FROM ( SELECT DistrictName + ''-'' + StyleID AS GP
, [去年系列數量]
, N''[去年系列數量]'' as [區域/風格]
FROM dbo.Sheet2
) AS SourceTable PIVOT
( SUM([去年系列數量]) FOR GP IN (' + @qty_columns + ' ) )
AS p3
UNION ALL
SELECT *
FROM ( SELECT DistrictName + ''-'' + StyleID AS GP
, [去年系列銷售金額]
, N''[去年系列銷售金額]'' as [區域/風格]
FROM dbo.Sheet2
) AS SourceTable PIVOT
( SUM([去年系列銷售金額]) FOR GP IN (' + @qty_columns + ' ) )
AS p4
UNION ALL
SELECT *
FROM ( SELECT DistrictName + ''-'' + StyleID AS GP
, [前年系列數量]
, N''[前年系列數量]'' as [區域/風格]
FROM dbo.Sheet2
) AS SourceTable PIVOT
( SUM([前年系列數量]) FOR GP IN (' + @qty_columns + ' ) )
AS p5
UNION ALL
SELECT *
FROM ( SELECT DistrictName + ''-'' + StyleID AS GP
, [前年系列銷售金額]
, N''[前年系列銷售金額]'' as [區域/風格]
FROM dbo.Sheet2
) AS SourceTable PIVOT
( SUM([前年系列銷售金額]) FOR GP IN (' + @qty_columns + ' ) )
AS p6 ) T2
');
所以,欄位就會依排序的方式來呈現哦!
參考資料
PIVOT使用多個彙總資料行(Multiple Aggregates)
Hi,
亂馬客Blog已移到了 「亂馬客 : Re:從零開始的軟體開發生活」
請大家繼續支持 ^_^