UNPIVOT

功能概述

UNPIVOT
UNPIVOT
把列转为行:把多个同类列(如
2012
2012
、
2013
2013
、
2014
2014
三列金额)收拢为“名称列 + 值列”两列,每个原始列变成一行。适合把报表宽表还原为便于聚合、关联的明细长表。

UNPIVOT
UNPIVOT
等价于多段
UNION ALL
UNION ALL
或
LATERAL VIEW stack(...)
LATERAL VIEW stack(...)
,但写法更短。反向操作(行转列)见 PIVOT。

语法

SELECT ... FROM <relation> UNPIVOT [ { INCLUDE | EXCLUDE } NULLS ] ( <value_column> FOR <name_column> IN (<col> [[AS] <alias>] [, ...]) ) [[AS] <alias>] -- 多值列 UNPIVOT [ { INCLUDE | EXCLUDE } NULLS ] ( (<value_col1>, <value_col2> [, ...]) FOR <name_column> IN ((<col1>, <col2> [, ...]) [[AS] <alias>] [, ...]) )

参数说明

  • { INCLUDE | EXCLUDE } NULLS
    { INCLUDE | EXCLUDE } NULLS
    :可选,默认
    EXCLUDE NULLS
    EXCLUDE NULLS
    ,即值为 NULL 的行被丢弃(多值列时所有值列都为 NULL 才丢弃)。需要保留 NULL 时写
    INCLUDE NULLS
    INCLUDE NULLS
    。

  • <value_column>
    <value_column>
    :新生成的值列的列名。多值列时写作
    (<value_col1>, <value_col2>)
    (<value_col1>, <value_col2>)
    。

  • <name_column>
    <name_column>
    :新生成的名称列的列名,内容是原始列名(或别名)。

  • IN (...)
    IN (...)
    :要收拢的原始列。多值列时每组写作
    (<col1>, <col2>)
    (<col1>, <col2>)
    ,个数与值列一致。各组的列类型需要兼容。

  • <alias>
    <alias>
    :可选,名称列中显示的名字。不写时,单值列显示原始列名;多值列显示用
    _
    _
    连接的原始列名,如
    earnings2012_sales2012
    earnings2012_sales2012
    。

未列在

IN
IN
中的列原样保留,作为每一行的标识列。

使用示例

前置数据:

CREATE OR REPLACE VIEW doc_course_earnings AS SELECT * FROM VALUES ('dotNET', 15000, 48000, 22500), ('Java', 20000, 30000, NULL) AS t(course, `2012`, `2013`, `2014`);

把三个年份列收拢为

year
year
、
earnings
earnings
两列:

SELECT * FROM doc_course_earnings UNPIVOT ( earnings FOR year IN (`2012`, `2013`, `2014`) ) ORDER BY course, year;

courseyearearnings
Java201220000
Java201330000
dotNET201215000
dotNET201348000
dotNET201422500

Java 的

2014
2014
为 NULL,默认被丢弃。保留 NULL 并为名称设置别名:

SELECT * FROM doc_course_earnings UNPIVOT INCLUDE NULLS ( earnings FOR year IN (`2012` AS y2012, `2013` AS y2013, `2014` AS y2014) ) WHERE course = 'Java' ORDER BY year;

courseyearearnings
Javay201220000
Javay201330000
Javay2014NULL

多值列:同时收拢每年的收入和销量。前置数据:

CREATE OR REPLACE VIEW doc_course_earnings_sales AS SELECT * FROM VALUES ('dotNET', 15000, NULL, 48000, 1), ('Java', 20000, 1, 30000, 2) AS t(course, earnings2012, sales2012, earnings2013, sales2013);

SELECT * FROM doc_course_earnings_sales UNPIVOT ( (earnings, sales) FOR year IN ((earnings2012, sales2012) AS `2012`, (earnings2013, sales2013) AS `2013`) ) ORDER BY course, year;

courseyearearningssales
Java2012200001
Java2013300002
dotNET201215000NULL
dotNET2013480001

dotNET 2012 年的

sales
sales
为 NULL,但
earnings
earnings
不为 NULL,所以这一行被保留。

注意事项

  • 默认
    EXCLUDE NULLS
    EXCLUDE NULLS
    ,值为 NULL 的行会被丢弃。
  • IN
    IN
    中各列的类型需要兼容。
  • 名称列中的内容是列名字符串,需要数值时自行
    CAST
    CAST
    。

相关文档

联系我们
预约咨询
微信咨询
电话咨询
邮件咨询