PIVOT 和 UNPIVOT 示例
PIVOT 示例
设置示例表和数据并使用它们运行后续示例查询。
CREATE TABLE part ( partname varchar, manufacturer varchar, quality int, price decimal(12, 2) ); INSERT INTO part VALUES ('P1', 'M1', 2, 10.00); INSERT INTO part VALUES ('P1', 'M2', NULL, 9.00); INSERT INTO part VALUES ('P1', 'M3', 1, 12.00); INSERT INTO part VALUES ('P2', 'M1', 1, 2.50); INSERT INTO part VALUES ('P2', 'M2', 2, 3.75); INSERT INTO part VALUES ('P2', 'M3', NULL, 1.90); INSERT INTO part VALUES ('P3', 'M1', NULL, 7.50); INSERT INTO part VALUES ('P3', 'M2', 1, 15.20); INSERT INTO part VALUES ('P3', 'M3', NULL, 11.80);
partname 上的 PIVOT,在 price 上有一个 AVG 聚合。
SELECT * FROM (SELECT partname, price FROM part) PIVOT ( AVG(price) FOR partname IN ('P1', 'P2', 'P3') );
查询将生成以下输出。
p1 | p2 | p3 -------+------+------- 10.33 | 2.71 | 11.50
上述的 PIVOT 示例结果等效于以下 GROUP BY 查询。但是,会将结果行转换为列名和列。
SELECT partname, avg(price) FROM (SELECT partname, price FROM part) WHERE partname IN ('P1', 'P2', 'P3') GROUP BY partname;
查询将生成以下输出。
partname | avg ----------+------- P1 | 10.33 P2 | 2.71 P3 | 11.50
一个 PIVOT 示例,将 manufacturer 作为隐式列。
SELECT * FROM (SELECT quality, manufacturer FROM part) PIVOT ( count(*) FOR quality IN (1, 2, NULL) );
查询将生成以下输出。
manufacturer | 1 | 2 | null --------------+---+---+------ M1 | 1 | 1 | 1 M2 | 1 | 1 | 1 M3 | 1 | 0 | 2
PIVOT 定义中未引用的输入表列被隐式添加到结果表中。就是上一个示例中 manufacturer 列这种情况。示例还显示,对于 IN 运算符,NULL 为有效值。
上述示例中的 PIVOT 返回与以下查询类似的信息,其中包含 GROUP BY。唯一的区别在于 PIVOT 为列 2 和 制造商 M3 返回值 0 GROUP BY 查询不包含相应的行。在大多数情况下,如果某行没有针对给定列的输入数据,PIVOT 会插入 NULL。但是,计数汇总不会返回 NULL,并将 0 用作默认值。
SELECT manufacturer, quality, count(*) FROM (SELECT quality, manufacturer FROM part) WHERE quality IN (1, 2) OR quality IS NULL GROUP BY manufacturer, quality;
查询将生成以下输出。
manufacturer | quality | count --------------+---------+------- M1 | 1 | 1 M1 | 2 | 1 M1 | | 1 M2 | 1 | 1 M2 | 2 | 1 M2 | | 1 M3 | 1 | 1 M3 | | 2
PIVOT 运算符接受聚合表达式和 IN 运算符的每个值上的可选别名。使用别名自定义列名。如果没有聚合别名,则仅使用 IN 列表别名。否则,将聚合别名附加到列名,并使用下划线将其与列名分开。
SELECT * FROM (SELECT quality, manufacturer FROM part) PIVOT ( count(*) AS count FOR quality IN (1 AS high, 2 AS low, NULL AS na) );
查询将生成以下输出。
manufacturer | high_count | low_count | na_count --------------+------------+-----------+---------- M1 | 1 | 1 | 1 M2 | 1 | 1 | 1 M3 | 1 | 0 | 2
以下是 PIVOT 的使用说明。
PIVOT可以应用于表、子查询和公用表表达式(CTE)。PIVOT不可应用于任何JOIN表达式、递归 CTE、PIVOT或UNPIVOT表达式。此外,也不支持SUPER取消嵌套的表达式和 Redshift Spectrum 嵌套表。PIVOT目前支持COUNT、SUM、MIN、MAX和AVG聚合函数。PIVOT聚合表达式必须是对受支持的聚合函数的调用。不支持聚合顶部的复杂表达式。聚合参数仅可包含对PIVOT输入表的引用。此外,也不支持对父查询的关联引用。聚合参数可能包含以下子查询:可以在内部关联的子查询或位于PIVOT输入表之上的子查询。PIVOT IN列表值不得为列引用或子查询。每个值必须与FOR列引用类型兼容。如果
IN列表值没有别名,PIVOT将生成默认的列名。对于常量IN值(例如“abc”或 5),默认列名是常量本身。对于任何复杂表达式,列名都是标准的 Redshift 默认名称,例如?column?。
UNPIVOT 示例
设置示例数据并使用它来运行后续示例。
CREATE TABLE count_by_color (quality varchar, red int, green int, blue int); INSERT INTO count_by_color VALUES ('high', 15, 20, 7); INSERT INTO count_by_color VALUES ('normal', 35, NULL, 40); INSERT INTO count_by_color VALUES ('low', 10, 23, NULL);
红、绿和蓝输入列上的 UNPIVOT。
SELECT * FROM (SELECT red, green, blue FROM count_by_color) UNPIVOT ( cnt FOR color IN (red, green, blue) );
查询将生成以下输出。
color | cnt -------+----- red | 15 red | 35 red | 10 green | 20 green | 23 blue | 7 blue | 40
默认情况下,将跳过输入列中的 NULL 值,且不会产生结果行。
以下示例显示了带有 INCLUDE NULLS 的 UNPIVOT。
SELECT * FROM ( SELECT red, green, blue FROM count_by_color ) UNPIVOT INCLUDE NULLS ( cnt FOR color IN (red, green, blue) );
以下是结果输出。
color | cnt -------+----- red | 15 red | 35 red | 10 green | 20 green | green | 23 blue | 7 blue | 40 blue |
如果已设置 INCLUDING NULLS 参数,NULL 输入值将生成结果行。
带有 quality 的 The following query shows UNPIVOT 作为隐式列。
SELECT * FROM count_by_color UNPIVOT ( cnt FOR color IN (red, green, blue) );
查询将生成以下输出。
quality | color | cnt ---------+-------+----- high | red | 15 normal | red | 35 low | red | 10 high | green | 20 low | green | 23 high | blue | 7 normal | blue | 40
UNPIVOT 定义中未引用的输入表列被隐式添加到结果表中。在该示例中,quality 列就是这种情况。
以下示例显示了带有 UNPIVOT 列表中值别名的 IN。
SELECT * FROM count_by_color UNPIVOT ( cnt FOR color IN (red AS r, green AS g, blue AS b) );
上一查询将产生以下输出。
quality | color | cnt ---------+-------+----- high | r | 15 normal | r | 35 low | r | 10 high | g | 20 low | g | 23 high | b | 7 normal | b | 40
UNPIVOT 运算符接受每个 IN 列表值上的可选别名。每个别名会提供每个 value 列中的数据自定义。
以下是 UNPIVOT 的使用说明。
UNPIVOT可以应用于表、子查询和公用表表达式(CTE)。UNPIVOT不可应用于任何JOIN表达式、递归 CTE、PIVOT或UNPIVOT表达式。此外,也不支持SUPER取消嵌套的表达式和 Redshift Spectrum 嵌套表。UNPIVOT IN列表必须仅包含输入表列引用。IN列表列必须具有它们都与之兼容的常见类型。UNPIVOT值列具有这一常见类型。UNPIVOT名称列属于类型VARCHAR。如果
IN列表值没有别名,UNPIVOT则使用列名作为默认值。