数据透视
数据透视是一种对数据进行分组和聚合的技术,可将数据从行状态转换为列状态。在所有数据透视查询中,您需要确定三个元素:
模式:
WITH PivotData AS
(
SELECT
< grouping column >,
< spreading column >,
< aggregation column >
FROM < source table >
)
SELECT < select list >
FROM PivotData
PIVOT( < aggregate function >(< aggregation column >)
FOR < spreading column > IN (< distinct spreading values >) ) AS P;
我在SQL Server中创建了此表
CREATE TABLE [dbo].[NameValueData](
[Name] [VARCHAR](50) NOT NULL,
[Value] [INT] NOT NULL
) ON [PRIMARY]
它具有值
INSERT INTO NameValueData
VALUES
( 'N1', 1 ),
( 'N2', 2 ),
( 'N3', 3 ),
( 'N4', 4 ),
--NOT FIXED Number of ROWS
数据是:
Name Value
N1 1
N2 2
N3 3
N4 4
... ...
现在,我需要旋转该数据并获得结果,其中基于列名中的行值创建的列名
N1 N2 N3 N4 ...
1 2 3 4 --Can be more
我试图编写自己的数据透视SQL
WITH PivotData
AS (SELECT Value AS GroupingColumn,
Name AS SpreadingColumn,
Value AS AggregationColumn
FROM dbo.NameValueData)
SELECT 1 AS Ignore,
[N1],
[N2],
[N3],
[N4]
FROM PivotData
PIVOT
(
MAX(AggregationColumn)
FOR SpreadingColumn IN ([N1], [N2], [N3], [N4])
) AS P;
结果是:
Ignore N1 N2 N3 N4
1 1 NULL NULL NULL
1 NULL 2 NULL NULL
1 NULL NULL 3 NULL
1 NULL NULL NULL 4
为什么我在这里得到4行?
答案 0 :(得分:2)
如果您将选择列表中的1 AS Ignore
替换为GroupingColumn
,将会看到为什么得到4条记录而不是一条记录的原因。
执行聚合时,PIVOT
操作使用所有分组列,无论是否包含在最终投影中,都包含在隐式group by
子句中。
从GroupingColumn
CTE和最终预测中删除PivotData
将解决您的问题。
实际上,由于数据的性质,您可以完全摆脱CTE,只需使用以下查询即可:
select *
from namevaluedata
pivot (max(value)
for name in ([N1], [N2], [N3], [N4])
) p;
答案 1 :(得分:1)
尝试一下:
WITH PivotData
AS (SELECT Name AS SpreadingColumn,
Value AS AggregationColumn
FROM dbo.NameValueData)
SELECT 1 AS Ignore,
[N1],
[N2],
[N3],
[N4]
FROM PivotData
PIVOT
(
MAX(AggregationColumn)
FOR SpreadingColumn IN ([N1], [N2], [N3], [N4])
) AS P;
答案 2 :(得分:0)
我只是不喜欢pivot
,更喜欢条件聚合。这就是原因之一。
正在生成的行由源数据中PIVOT
子句中所有不是 的值确定。因为您有第三列(GroupingColumn
),所以它用于定义行。