问题 请解释一下PIVOT的部分内容


我看过很多博客文章。我已经阅读了文档。我通常相当擅长提取新东西,但即使我继续阅读,但我只是不理解SQL Server(2008)中的PIVOT部分。

有人可以把它给我,好又慢。 (即傻瓜的枢轴)

如果需要一个例子,那么我们可以使用那个 在这个问题上

以下是我尝试转动该示例的方法:

SELECT OtherID, Val1, Val2, Val3, Val4, Val5
FROM 
    (SELECT OtherID, Val
    FROM @randomTable) p
PIVOT
(
    max(val)
    FOR Val IN (Val1, Val2, Val3, Val4, Val5)
) AS PivotTable;

上面的查询给出了空值而不是Val1,Val2 ...列中的值。

但要明确, 我不是在寻找一个固定的查询。我需要 理解 PIVOT,因为我正在寻找比这个例子更复杂的东西。

具体来说,聚合的交易是什么?我只想获取与给定ID匹配的所有字符串值并将它们放在同一行中。我不想聚集任何东西。 (再看一遍 这个问题 为我的例子。)


10193
2018-03-26 16:06


起源



答案:


数据透视查询的说明

FROM 
    (SELECT OtherID, Val, amount
    FROM @randomTable) p

这些是成为数据透视表“基础数据”的列。不要包含不执行任何操作的列。正如您没有将非GROUP BY列放入SELECT子句一样,您也不会在PIVOT源中列出未使用的列。

PIVOT
(
    max(amount)
    FOR Val IN (Val1, Val2, Val3, Val4, Val5)
) AS PivotTable;

这部分表示您正在创建5个名为“Val1”到“Val5”的新列。这些列名称代表  在Val列中。所以预计你的表将包含这样的东西

otherID   Val     amount
1         Val1    1
2         Val2    2
1         Val3    3
1         Val1    5
(etc)     (this column contains one of Val1 - Val5, or null)

所以你现在有5个以前不存在的新列。什么进入专栏?

  • OUTPUT中不是PIVOTed列的任何列都是“GROUP BY”列。
  • 聚合函数将所有数据收集到作为GROUP BY列和PIVOTED列之间的CROSS的单元格中。

因此,为了说明,使用上面的示例数据,我们有otherID = 1和val = Val1。在输出表中,只有一个单元格表示每个(其他ID / val)组合的Max(金额)组合

otherID   Val1   Val2   Val3   Val4   Val5
1         <x>    ...    ...    ...    ...
(etc)

对于标记的单元格 <x> ,只允许一个值,所以 <x> 不能包含多个 amount 值。这就是为什么我们需要聚合它,在这种情况下使用 MAX(amount)。事实上,输出看起来像这样

(unpivoted columns)   (pivoted, creates "new" columns)
otherID             |  Val1          Val2           Val3   Val4   Val5
1                   |  MAX(amount)   Max(amount)    << cell value = aggregate function
(etc)

然后SELECT语句输出这些列

SELECT OtherID, Val1, Val2, Val3, Val4, Val5

14
2018-03-26 19:10



这是一个很棒的解释!我现在明白了。我遗漏的一件大事是新列名称必须是现有值。 - Vaccano
我也意识到这意味着我不能使用枢轴。 (我不知道要在前面转动的列名。) - Vaccano
@Vaccano在SO或Google上搜索“sql server dynamic pivot”。它构建了一个使用PIVOT(或旧样式)的动态SQL语句 MAX(CASE 枢转)。 - RichardTheKiwi
@Vaccano:是的,你可以,如果你使用的话 ROW_NUMBER() 功能就像 马丁 有人建议。 - Andriy M


答案:


数据透视查询的说明

FROM 
    (SELECT OtherID, Val, amount
    FROM @randomTable) p

这些是成为数据透视表“基础数据”的列。不要包含不执行任何操作的列。正如您没有将非GROUP BY列放入SELECT子句一样,您也不会在PIVOT源中列出未使用的列。

PIVOT
(
    max(amount)
    FOR Val IN (Val1, Val2, Val3, Val4, Val5)
) AS PivotTable;

这部分表示您正在创建5个名为“Val1”到“Val5”的新列。这些列名称代表  在Val列中。所以预计你的表将包含这样的东西

otherID   Val     amount
1         Val1    1
2         Val2    2
1         Val3    3
1         Val1    5
(etc)     (this column contains one of Val1 - Val5, or null)

所以你现在有5个以前不存在的新列。什么进入专栏?

  • OUTPUT中不是PIVOTed列的任何列都是“GROUP BY”列。
  • 聚合函数将所有数据收集到作为GROUP BY列和PIVOTED列之间的CROSS的单元格中。

因此,为了说明,使用上面的示例数据,我们有otherID = 1和val = Val1。在输出表中,只有一个单元格表示每个(其他ID / val)组合的Max(金额)组合

otherID   Val1   Val2   Val3   Val4   Val5
1         <x>    ...    ...    ...    ...
(etc)

对于标记的单元格 <x> ,只允许一个值,所以 <x> 不能包含多个 amount 值。这就是为什么我们需要聚合它,在这种情况下使用 MAX(amount)。事实上,输出看起来像这样

(unpivoted columns)   (pivoted, creates "new" columns)
otherID             |  Val1          Val2           Val3   Val4   Val5
1                   |  MAX(amount)   Max(amount)    << cell value = aggregate function
(etc)

然后SELECT语句输出这些列

SELECT OtherID, Val1, Val2, Val3, Val4, Val5

14
2018-03-26 19:10



这是一个很棒的解释!我现在明白了。我遗漏的一件大事是新列名称必须是现有值。 - Vaccano
我也意识到这意味着我不能使用枢轴。 (我不知道要在前面转动的列名。) - Vaccano
@Vaccano在SO或Google上搜索“sql server dynamic pivot”。它构建了一个使用PIVOT(或旧样式)的动态SQL语句 MAX(CASE 枢转)。 - RichardTheKiwi
@Vaccano:是的,你可以,如果你使用的话 ROW_NUMBER() 功能就像 马丁 有人建议。 - Andriy M