- 类别:
PIVOT¶
通过将输入表达式中的一列中的唯一值转换为多列并根据需要聚合任何剩余列值的结果来旋转表。在查询中,它在表名或子查询后面的 FROM 子句中指定。
PIVOT 支持以下 内置聚合函数:
PIVOT 可用于将窄表(例如 empid、month、sales)转换为更宽的表(例如 empid、jan_sales、feb_sales、mar_sales)。
- 另请参阅:
语法¶
参数¶
aggregate_function用于组合来自
pivot_column的分组值的聚合函数。pivot_column [ [ AS ] alias ]源表或子查询中将被汇总的列。
可选
[ AS ] alias子句指定要在 PIVOT 操作结果中用于聚合的别名。下划线和别名将追加到每个透视列名称。例如,如果alias是total,透视操作会将_TOTAL追加到透视列名称。AS 关键字是可选的。value_column源表或子查询中的列,其中包含将用于生成列名的值。
pivot_value_N [ [ AS ] alias ]将数据透视列的值列表转换为查询结果中的标题。
可选
[ AS ] alias子句指定要用于 PIVOT 操作结果中值的别名。别名将取代值。ANY [ ORDER BY ... ]-
对透视列的所有不同值执行透视。要控制输出中透视列的顺序,请在 ANY 关键字后指定 ORDER BY 子句。如果透视列包含 NULLs,则 NULL 也被视为透视值。
subquery-
对在子查询中找到的所有值执行透视。如果子查询包含 ORDER BY 子句,则需要 DISTINCT 关键字。子查询必须是返回单个列的不相关子查询。对子查询返回的所有不同值执行透视。有关不相关子查询的信息,请参阅 使用子查询。
DEFAULT ON NULL(value)使用指定的默认值替换透视结果中的所有 NULL 值。默认值可以是任何不依赖于透视和聚合列的标量表达式。
使用说明¶
Snowflake 支持 动态透视。动态透视查询使用 ANY 关键字或 PIVOT 分子句中的子查询,而不是显式指定透视值。
在 视图 定义中使用动态透视时,如果底层数据发生变化,导致透视输出列发生变化,则在视图上执行的查询可能会失败。
在存储过程或用户定义的函数 (UDF) 的主体中不支持动态透视。
不使用动态透视的透视查询可以返回含有重复列的输出。我们建议避免含有重复列的输出。动态透视查询会对重复列进行去重。
如果不使用动态透视的透视查询尝试执行以下操作,则可能会失败:将 VARIANT 列 CAST 为不同的数据类型。动态透视查询没有此限制。
目前,PIVOT 语义不允许多重聚合,但您可以使用 PIVOT 及 UNION 运算符 来实现类似的结果。有关示例,请参阅 使用 UNION 对多重聚合执行动态透视。
示例¶
PIVOT 示例使用以下 quarterly_sales 表:
以下示例使用 PIVOT:
自动对所有不同的列值执行动态透视¶
给定表 quarterly_sales,使用 ANY 关键字来计算所有不同季度每位员工的总销售额之和,以对 amount 列执行透视,并通过指定 ORDER BY 使透视列按顺序排列:
以下示例与前面的示例相同,但它会将别名 _TOTAL 追加到每个透视列名称:
使用子查询对列值执行动态透视¶
假设除了 quarterly_sales 表之外,ad_campaign_types_by_quarter 表也在跟踪在特定季度投放的广告的类型。该表具有以下结构和数据:
您可以在透视查询中使用子查询来确定开展了特定广告活动的季度的销售额总和。例如,以下透视查询仅返回开展了电视广告活动的季度的数据:
使用 UNION 对多重聚合执行动态透视¶
您可以使用 UNION 运算符 在单个结果集中显示多个聚合。本例使用动态透视和 UNION 运算符显示每个季度每位员工的以下信息:
使用 AVG 函数计算单笔销售的平均金额。
使用 MAX 函数确定价值最高的销售。
使用 MIN 函数确定价值最低的销售。
使用 COUNT 函数确定销售笔数。
使用 SUM 函数计算所有销售的总额。
运行查询:
对联接查询执行动态透视¶
要在带联接的查询中执行透视,可以使用 通用表表达式 (CTE) 进行透视查询。
例如,假设有一个简单的表将员工映射到经理:
运行一个查询,联接 emp_manager 表和 quarterly_sales 表,并对 quarterly_sales 表中的 amount 列执行透视:
对透视列的指定列值列表执行透视¶
给定表 quarterly_sales,对 amount 列执行透视,以计算指定季度每个员工的总销售额之和:
通过运行以下查询,可以对 amount 列中的所有季度执行透视:
您可以使用 AS 子句修改输出中的列名。例如,要缩短列名并显示不带引号的列名,请运行以下查询:
使用默认值替换 NULL 值的透视¶
如果查询返回 NULL 值,您可以通过 DEFAULT ON NULL 来用默认值替换这些值。例如,您可以使用动态透视,并通过运行以下查询来用默认值 0 替换 NULL 值:
您还可以使用 DEFAULT ON NULL 和指定的列列表:
涉及多列的透视示例¶
透视查询可以涉及多列。在运行这些示例之前,请在 quarterly_sales 表中添加一列,并在该列中填入随机值。
首先,在 quarterly_sales 表中添加一列,跟踪每笔销售应用的折扣:
用 0 和 5 之间的随机值填充新列,用于指定每笔销售的折扣百分比:
查询表以显示已添加随机值的新列:
在新列已添加并填充完毕后,运行以下示例:
使用 CTE 从透视查询中排除列¶
可以使用 通用表表达式 (CTE) 从数据透视查询中排除列。
下面的示例使用 CTE 将 discount_percent 列排除在数据透视查询之外:
您可以使用 CTE 来排除 amount 列,并显示每位员工在每个季度提供的平均折扣:
运行多维透视查询¶
多维透视查询对多个列执行透视。本示例对 amount 列和 discount_percentage 列进行透视。该查询会返回每个季度所有员工的所有销售额总和,以及每个季度所有销售的最大折扣百分比。
在查询中,SELECT 列表使用 $col_position 参数依次对返回的列运行 SUM 和 MAX 函数,并为返回的列命名。FROM 子查询为透视操作提供数据。由于输出结果显示的是所有员工的销售结果,因此子查询不包括 empid 列。