SQL Pivot(透视)是一种将行数据转换为列数据的操作,它可以将数据表中的某一列的值作为新表的列名,同时聚合其他列的数据。多列Pivot则是在此基础上同时对多个列进行透视操作。
-- 假设有销售数据表 SalesData(ProductID, Region, Quarter, Amount)
SELECT ProductID, [North], [South], [East], [West]
FROM
(
SELECT ProductID, Region, Quarter, Amount
FROM SalesData
) AS SourceTable
PIVOT
(
SUM(Amount)
FOR Region IN ([North], [South], [East], [West])
) AS PivotTable;
SELECT
ProductID,
SUM(CASE WHEN Region = 'North' THEN Amount ELSE 0 END) AS North,
SUM(CASE WHEN Region = 'South' THEN Amount ELSE 0 END) AS South,
SUM(CASE WHEN Region = 'East' THEN Amount ELSE 0 END) AS East,
SUM(CASE WHEN Region = 'West' THEN Amount ELSE 0 END) AS West
FROM SalesData
GROUP BY ProductID;
SELECT * FROM crosstab(
'SELECT ProductID, Region, SUM(Amount)
FROM SalesData
GROUP BY ProductID, Region
ORDER BY 1,2',
'SELECT DISTINCT Region FROM SalesData ORDER BY 1'
) AS ct (ProductID int, North numeric, South numeric, East numeric, West numeric);
原因:需要透视的列值在编写SQL时未知或会变化
解决方案:
-- SQL Server动态Pivot示例
DECLARE @columns NVARCHAR(MAX) = '';
DECLARE @sql NVARCHAR(MAX) = '';
-- 获取所有不重复的Region值作为列名
SELECT @columns = @columns + QUOTENAME(Region) + ','
FROM (SELECT DISTINCT Region FROM SalesData) AS temp;
SET @columns = LEFT(@columns, LEN(@columns) - 1);
-- 构建动态SQL
SET @sql = '
SELECT ProductID, ' + @columns + '
FROM
(
SELECT ProductID, Region, Amount
FROM SalesData
) AS SourceTable
PIVOT
(
SUM(Amount)
FOR Region IN (' + @columns + ')
) AS PivotTable;';
EXEC sp_executesql @sql;
原因:需要同时对多个数值列进行透视
解决方案:
-- 同时透视Amount和Quantity
SELECT
ProductID,
SUM(CASE WHEN Region = 'North' THEN Amount ELSE 0 END) AS North_Amount,
SUM(CASE WHEN Region = 'North' THEN Quantity ELSE 0 END) AS North_Quantity,
SUM(CASE WHEN Region = 'South' THEN Amount ELSE 0 END) AS South_Amount,
SUM(CASE WHEN Region = 'South' THEN Quantity ELSE 0 END) AS South_Quantity
FROM SalesData
GROUP BY ProductID;
原因:大数据量下Pivot操作可能较慢
解决方案:
-- 同时按Region和Quarter透视
SELECT ProductID,
-- North区域各季度
SUM(CASE WHEN Region = 'North' AND Quarter = 'Q1' THEN Amount ELSE 0 END) AS North_Q1,
SUM(CASE WHEN Region = 'North' AND Quarter = 'Q2' THEN Amount ELSE 0 END) AS North_Q2,
-- South区域各季度
SUM(CASE WHEN Region = 'South' AND Quarter = 'Q1' THEN Amount ELSE 0 END) AS South_Q1,
SUM(CASE WHEN Region = 'South' AND Quarter = 'Q2' THEN Amount ELSE 0 END) AS South_Q2
FROM SalesData
GROUP BY ProductID;
Pivot操作是SQL中强大的数据转换工具,掌握多列Pivot技术可以大大简化复杂报表的生成过程。
没有搜到相关的文章