Dav*_*ugg 8 sql t-sql sql-server pivot
我知道很多人都观察过这种行为,但我想知道是否有人可以解释原因.当我创建一个小表来创建使用pivot函数的示例时,我得到了我期望的结果:
CREATE TABLE dbo.AverageFishLength
(
Fishtype VARCHAR(50) ,
AvgLength DECIMAL(8, 2) ,
FishAge_Years INT
)
INSERT INTO dbo.AverageFishLength
( Fishtype, AvgLength, FishAge_Years )
VALUES ( 'Muskie', 32.75, 3 ),
( 'Muskie', 37.5, 4 ),
( 'Muskie', 39.75, 5 ),
( 'Walleye', 16.5, 3 ),
( 'Walleye', 18.25, 4 ),
( 'Walleye', 20.0, 5 ),
( 'Northern Pike', 20.75, 3 ),
( 'Northern Pike', 23.25, 4 ),
( 'Northern Pike', 26.0, 5 );
Run Code Online (Sandbox Code Playgroud)
这是透视查询:
SELECT Fishtype ,
[3] AS [3 Years Old] ,
[4] AS [4 Years Old] ,
[5] AS [5 Years Old]
FROM dbo.AverageFishLength PIVOT( SUM(AvgLength)
FOR FishAge_Years IN ( [3], [4], [5] ) ) AS PivotTbl
Run Code Online (Sandbox Code Playgroud)
结果如下:
但是,如果我使用标识列创建表,则结果将分成不同的行:
DROP TABLE dbo.AverageFishLength
CREATE TABLE dbo.AverageFishLength
(
ID INT IDENTITY(1,1) ,
Fishtype VARCHAR(50) ,
AvgLength DECIMAL(8, 2) ,
FishAge_Years INT
)
INSERT INTO dbo.AverageFishLength
( Fishtype, AvgLength, FishAge_Years )
VALUES ( 'Muskie', 32.75, 3 ),
( 'Muskie', 37.5, 4 ),
( 'Muskie', 39.75, 5 ),
( 'Walleye', 16.5, 3 ),
( 'Walleye', 18.25, 4 ),
( 'Walleye', 20.0, 5 ),
( 'Northern Pike', 20.75, 3 ),
( 'Northern Pike', 23.25, 4 ),
( 'Northern Pike', 26.0, 5 );
Run Code Online (Sandbox Code Playgroud)
同样的查询:
SELECT Fishtype ,
[3] AS [3 Years Old] ,
[4] AS [4 Years Old] ,
[5] AS [5 Years Old]
FROM dbo.AverageFishLength PIVOT( SUM(AvgLength)
FOR FishAge_Years IN ( [3], [4], [5] ) ) AS PivotTbl
Run Code Online (Sandbox Code Playgroud)
结果不同:
在我看来,ID列正在查询中使用,即使它根本没有出现在查询中.它几乎就像隐含在查询中,但未在结果集中显示.
谁能解释为什么会这样?
Tar*_*ryn 13
之所以会发生这种情况是因为该ID
列对于每一行都是唯一的,并且由于您直接查询表(没有子查询),该列作为GROUP BY
聚合函数需求的一部分包含在内.
该文档的约MSDN文档FROM
状态如下:
table_source PIVOT <pivot_clause>
指定table_source基于pivot_column进行透视.table_source是表或表的表达式.输出是一个表,其中包含table_source的所有列,pivot_column和value_column除外.除了pivot_column和value_column之外,table_source的列称为pivot运算符的分组列.
PIVOT
对输入表执行关于分组列的分组操作,并为每个组返回一行.此外,输出包含在column_list中指定的每个值的一列,该列出现在input_table的pivot_column中.
你的版本基本上是在说SELECT * FROM yourtable
PIVOT那个数据.即使ID
列不在最终的SELECT列表中,它也是查询中的分组元素.如果您将PIVOT与"pre-PIVOT"示例进行比较,以显示您将看到您的版本.此示例使用CASE表达式和聚合函数:
SELECT Fishtype,
sum(case when FishAge_Years = 3 then AvgLength else 0 end) as [3],
sum(case when FishAge_Years = 4 then AvgLength else 0 end) as [4],
sum(case when FishAge_Years = 5 then AvgLength else 0 end) as [5]
FROM dbo.AverageFishLength
GROUP BY Fishtype, ID;
Run Code Online (Sandbox Code Playgroud)
结果将会有所偏差,因为即使您没有ID
最终列表,它仍然被用于分组,因为它们是唯一的,您将得到多行.
使用PIVOT时解决此问题的最简单方法是使用子查询:
SELECT Fishtype ,
[3] AS [3 Years Old] ,
[4] AS [4 Years Old] ,
[5] AS [5 Years Old]
FROM
(
SELECT Fishtype,
AvgLength,
FishAge_Years
FROM dbo.AverageFishLength
) d
PIVOT
(
SUM(AvgLength)
FOR FishAge_Years IN ( [3], [4], [5] )
) AS PivotTbl;
Run Code Online (Sandbox Code Playgroud)
在此版本中,您只返回表中实际需要和想要的列 - 这不包括在内,ID
因此不会用于对数据进行分组.
归档时间: |
|
查看次数: |
450 次 |
最近记录: |