为什么在SQL Server中转动文本列时使用Max函数?

Sor*_*ath 5 sql t-sql sql-server pivot

我刚学会了如何在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
Run Code Online (Sandbox Code Playgroud)

Stu*_*tLC 6

因为在您的示例中,您已选择EVENT作为要在 PIVOT 交叉点中显示的值(即,因为您已EVENT在子句中指定),所以必须使用允许的聚合函数PIVOT之一指定该值,因为每个聚合函数可能有多行当按剩余列(即您的情况下的“日期”)分组时,您在数据透视表中选择的列值的数量。

在 Sql Server [1]中,MAX()orMIN()通常在旋转非数字列时使用,因为它能够显示列的原始值之一。

任何非聚合和非透视列将保持原样,并将用于形成透视所基于的组(在您的情况下,列DATE既不在聚合中,也不在列透视中,因此它将形成行组)

考虑这样的情况:您的数据透视表包含与您的谓词匹配的多行,如下所示:

INSERT INTO strategy (DATE, SITA, EVENT) VALUES
('1 Jan 2018', 'ABZPD', 'Event1'),
('1 Jan 2018', 'BFSPD', 'Event2'),
('1 Jan 2018', 'BFSPD', 'Event3');
Run Code Online (Sandbox Code Playgroud)

枢轴后:

DATE                    ABZPD   BFSPD
2018-01-01T00:00:00Z    Event1  Event3
Run Code Online (Sandbox Code Playgroud)

即在枢轴期间,和 的BFSPD行需要以某种方式投影到单个单元格中 - 因此需要聚合。即使已知只有一个值(上例中SITA 的值就是这种情况),仍然需要这一聚合。Event2Event3Event1ABZPD

由于BFSPD有两个事件,您需要以某种方式解决如何将值投影到单个单元格值中的问题。在投影到同一结果数据透视“单元格”中的多行情况下,MAX在 VARCHAR 列上使用可以解析“最大”值 ( ) -此处的 SqlFiddle 示例Event3

您可以选择用于COUNT(Event)显示每行/枢轴交叉点的事件数 - Fiddle

EVENT您可以使用DATE-来打开聚合,EVENT从而在列分组中使用。


*1 像AVG或 之类的聚合STDEV显然不适用于字符串。其他 RDBMS 具有其他聚合,例如FIRST,它将任意采用第一个值,或GROUP_CONCAT / LIST_AGG,它可以将字符串值与分隔符折叠在一起。PostGres允许您创建自己的聚合函数!但遗憾的是,SqlServer 中没有这些,因此目前使用 MIN() / MAX() 。