Pivot和Undivot操作员
#sql #database #分析

PIVOTUNPIVOT是Transact-SQL运算符,用于将行转换为列,反之亦然。这些操作员从2005年版本添加到SQL Server中。在此之前,只有一种方法如何转动数据。这是SELECT...CASE语句的复杂系列。

PIVOT通过将唯一值从一个列转换为输出中的多个列来旋转表值表达式。 PIVOT还可以在最终输出中出现的所有剩余列值上运行聚合。 PIVOT对于数年,季度,月份等可视化数据很有用

让S一个简单的示例检查PIVOT语法。以下是一张桌子,到2022年至2023年的员工收入。

CREATE TABLE Employees (
    Employee_Id INT,
    [Year] INT,
    [Quarter] INT,
    Income MONEY)

INSERT Employees VALUES(1, 2022, 1, 100000)
INSERT Employees VALUES(1, 2022, 2, 100000)
INSERT Employees VALUES(1, 2022, 3, 100000)
INSERT Employees VALUES(1, 2022, 4, 150000)
INSERT Employees VALUES(1, 2023, 1, 100000)
INSERT Employees VALUES(2, 2022, 2, 90000)
INSERT Employees VALUES(2, 2022, 3, 95000)
INSERT Employees VALUES(2, 2022, 4, 90000)
INSERT Employees VALUES(2, 2023, 1, 120000)
INSERT Employees VALUES(3, 2023, 1, 200000)
员工_id 四分之一 收入
1 2022 1 100000,00
1 2022 2 100000,00
1 2022 3 100000,00
1 2022 4 150000,00
1 2023 1 100000,00
2 2022 2 90000,00
2 2022 3 95000,00
2 2022 4 90000,00
2 2023 1 120000,00
3 2023 1 200000,00

现在,我们只想为每个员工提供一行,但全年都有数据。

SELECT Employee_Id, [2022], [2023]
FROM 
(
    SELECT Employee_Id, [Year], Income FROM Employees
) AS source_query
PIVOT
(
    SUM(Income) FOR [Year] IN ([2022], [2023])
) AS pivoted_table
员工_id 2022 2023
1 450000,00 100000,00
2 275000,00 120000,00
3 null 200000,00

您可以看到,而不是10行,我们只为每个员工得到3行。 PIVOT从一列[年]中创建了两列[2022]和[2023],收益总和。汇总(上面的示例中的SUM)在PIVOT中是强制性的。

另外,请注意,如果某些列没有数据,则SQL Server将NULLs放入其中,因为它对员工3在2022年发生。但是枢轴内部的集合函数在值列中不考虑null值。如您所见,员工2在2022年第一季度没有收入,但总函数计算得正确。

不分散

UNPIVOT通过将列转换为行将旋转的表旋转回去。但是它不会汇总值或以任何方式更改它们。 UNPIVOT也不显示NULL值。它们只是在输出中消失。

让我们看一下我们的上一个示例,并从枢纽结果集创建一个表。

CREATE TABLE Pivoted_Employees(
    Employee_Id INT,
    [2022] MONEY,
    [2023] MONEY
)

INSERT Pivoted_Employees VALUES(1, 450000, 100000)
INSERT Pivoted_Employees VALUES(2, 450000, 120000)
INSERT Pivoted_Employees VALUES(3, NULL, 200000)

现在,我们将尝试将年的专栏变成行。

select Employee_Id, [Year], Income
from (
    select Employee_Id, [2022], [2023]
    from Pivoted_Employees
) as pivoted_employees
unpivot(
    Income for [Year] in ([2022], [2023])
) as unpivoted_employees
员工_id 收入
1 2022 450000,00
1 2023 100000,00
2 2022 450000,00
2 2023 120000,00
3 2023 200000,00

结果集仅包含5行,因为UNPIVOT不知道原始表(在枢轴之前)有季度。

在结论中,当您知道结果集应包含多少列时,PIVOTUNPIVOT运算符对于转换数据很有用。如果不是,则需要使用更复杂的结构。