我刚学会了如何在SQL Server中进行透视。我想知道为什么在我们想要转动文本列时使用max
函数?这背后的逻辑是什么?我理解它是Count
,Sum
等(因为你对相应的行和列进行求和)但我不理解在有文本列时使用max
的逻辑?
例如,我的代码是:
SELECT *
FROM ( SELECT DATE
,SITA
,EVENT
FROM [UKRMC].[dbo].[strategy]
where datename(year, DATE) = 2018 or datename(year,DATE)=2019
) strategy
PIVOT ( max(EVENT)
FOR SITA IN ([ABZPD],[BFSPD]
,[BFSZH]
,[BHXPD]
,[BHXZH]
,[BRSZH]
,[BRUPQ] ) piv
答案 0 :(得分:2)
使用PIVOT
命令时必须指定聚合函数,因为透视操作的第一步是对FOR
子句中指定的列的分组操作,该操作减少了结果的行数表。
聚合函数用于管理输出表中所需的其他列的值。
来自Technet文档:
PIVOT通过转动唯一值来旋转表值表达式 从表达式中的一列到输出中的多个列, 并且执行任何剩余所需的聚合 最终输出中需要的列值。
以下是来自同一篇Technet文章的PIVOT
命令语法:
SELECT <non-pivoted column>,
[first pivoted column] AS <column name>,
[second pivoted column] AS <column name>,
...
[last pivoted column] AS <column name>
FROM
(<SELECT query that produces the data>)
AS <alias for the source query>
PIVOT
(
<aggregation function>(<column being aggregated>)
FOR
[<column that contains the values that will become column headers>]
IN ( [first pivoted column], [second pivoted column],
... [last pivoted column])
) AS <alias for the pivot table>
<optional ORDER BY clause>;
请注意,在PIVOT
子句之后,您必须指定聚合函数:
...
<aggregation function>(<column being aggregated>)
...
有关此主题的其他见解,另请参阅this Microsoft Press文章。
答案 1 :(得分:2)
因为在您的示例中,您已选择EVENT
作为PIVOT交叉点中显示的值(即,您已在EVENT
子句中指定PIVOT
,必须使用permissible aggregate functions之一指定值,因为当您按照其余列进行分组时,您在枢轴中选择的每个列值可能有多行(即DATE在您的列中)情况)。
在Sql Server [1] 中,MAX()
或MIN()
通常在旋转非数字列时使用,因为它能够显示其中一个原始的列的值。
任何非聚合和非旋转列都将保持原样,并将用于形成数据透视所基于的组(在您的情况下,列DATE
不在列中聚合或列枢轴,因此它将形成行组)
考虑您的透视表包含与谓词匹配的多行的情况,例如:
INSERT INTO strategy (DATE, SITA, EVENT) VALUES
('1 Jan 2018', 'ABZPD', 'Event1'),
('1 Jan 2018', 'BFSPD', 'Event2'),
('1 Jan 2018', 'BFSPD', 'Event3');
在Pivot之后:
DATE ABZPD BFSPD
2018-01-01T00:00:00Z Event1 Event3
即。在数据透视期间,BFSPD
和Event2
的{{1}}行需要以某种方式投射到单个单元格中 - 因此需要聚合。即使已知只有one value(在上例中SITA Event3
的{{1}}值就是这种情况),仍然需要此聚合。
由于Event1
有两个事件,您需要以某种方式解决如何将值投影到单个单元格值中的问题。在VARCHAR列上使用ABZPD
可以解析最大的&#39;值(BFSPD
)如果多行投影到相同的结果枢轴&#39;单元格&#39; - SqlFiddle example here
您可以选择使用MAX
向您显示每行/枢轴交叉点的事件数量 - Fiddle
您可以使用Event3
切换COUNT(Event)
上的聚合 - EVENT
DATE
中使用EVENT
。
* 1 AVG
或STDEV
等聚合显然不适用于字符串。其他RDBMS有额外的聚合,如column grouping,它将任意取第一个值,或FIRST,它可以将字符串值与分隔符一起折叠。并且GROUP_CONCAT / LIST_AGG允许您创建自己的聚合函数!但遗憾的是,在SqlServer中没有这个,因此MIN()
/ MAX()现在。