按某些列 SQL 旋转(转置)

Posted

技术标签:

【中文标题】按某些列 SQL 旋转(转置)【英文标题】:Pivot(transpose) by some columns SQL 【发布时间】:2020-07-28 12:04:35 【问题描述】:

我希望按表中的某些列进行转置。我有类似以下示例的内容:

╔════════╦═══════╦══════╦══════╦═════════╦══════╦═══════╦═══════╦═══════╦═══════╦═══════╦═══════╦═══════╗
║ name   ║ week  ║ colX ║ ColY ║ Col.... ║ ColZ ║ Day 1 ║ Day 2 ║ Day 3 ║ Day 4 ║ Day 5 ║ Day 6 ║ Day 7 ║
╠════════╬═══════╬══════╬══════╬═════════╬══════╬═══════╬═══════╬═══════╬═══════╬═══════╬═══════╬═══════╣
║ name x ║ week1 ║ xxx  ║ yyy  ║ ....    ║ zzz  ║ 0     ║ 5     ║ 0     ║ 0     ║ 0     ║ 0     ║ 0     ║
╠════════╬═══════╬══════╬══════╬═════════╬══════╬═══════╬═══════╬═══════╬═══════╬═══════╬═══════╬═══════╣
║ name Y ║ week1 ║ xxx  ║ yyy  ║ ....    ║ zzz  ║ 4     ║ 0     ║ 0     ║ 0     ║ 0     ║ 0     ║ 0     ║
╠════════╬═══════╬══════╬══════╬═════════╬══════╬═══════╬═══════╬═══════╬═══════╬═══════╬═══════╬═══════╣
║ name Z ║ week1 ║ xxx  ║ yyy  ║ ....    ║ zzz  ║ 0     ║ 0     ║ 5     ║ 0     ║ 5     ║ 0     ║ 0     ║
╠════════╬═══════╬══════╬══════╬═════════╬══════╬═══════╬═══════╬═══════╬═══════╬═══════╬═══════╬═══════╣
║ name x ║ week2 ║ xxx  ║ yyy  ║ ....    ║ zzz  ║ 0     ║ 0     ║ 0     ║ 5     ║ 5     ║ 0     ║ 0     ║
╠════════╬═══════╬══════╬══════╬═════════╬══════╬═══════╬═══════╬═══════╬═══════╬═══════╬═══════╬═══════╣
║ name Y ║ week2 ║ xxx  ║ yyy  ║ ....    ║ zzz  ║ 5     ║ 0     ║ 0     ║ 0     ║ 4     ║ 0     ║ 0     ║
╠════════╬═══════╬══════╬══════╬═════════╬══════╬═══════╬═══════╬═══════╬═══════╬═══════╬═══════╬═══════╣
║ name Z ║ week2 ║ xxx  ║ yyy  ║ ....    ║ zzz  ║ 0     ║ 4     ║ 5     ║ 4     ║ 0     ║ 0     ║ 2     ║
╚════════╩═══════╩══════╩══════╩═════════╩══════╩═══════╩═══════╩═══════╩═══════╩═══════╩═══════╩═══════╝

我想将信息转置为每行显示 1 天,其余信息按原样显示,我知道这将创建更多行,但有助于保持信息更清晰。

每行右侧显示 1 周,然后是该周的 7 天,以及分配给每个项目每天的小时数(比如说 colX 值)。 我试图仅按天进行转置,但我不知道如何仅将枢轴用于几个值。

【问题讨论】:

【参考方案1】:

以下是您的数据示例:

with t as (
select ' name x ' name,' week1 ' week,' xxx  ' colx,' yyy  ' coly,' ....    ' colxyz,' zzz  ' colz,' 0     'day1, ' 5     'day2, ' 0     'day3, ' 0     'day4, ' 0     ' day5,' 0     ' day6, ' 0     ' day7 union all
select ' name Y ',' week1 ',' xxx  ',' yyy  ',' ....    ',' zzz  ',' 4     ',' 0     ',' 0     ',' 0     ',' 0     ',' 0     ',' 0     ' union all
select ' name Z ',' week1 ',' xxx  ',' yyy  ',' ....    ',' zzz  ',' 0     ',' 0     ',' 5     ',' 0     ',' 5     ',' 0     ',' 0     ' union all
select ' name x ',' week2 ',' xxx  ',' yyy  ',' ....    ',' zzz  ',' 0     ',' 0     ',' 0     ',' 5     ',' 5     ',' 0     ',' 0     ' union all
select ' name Y ',' week2 ',' xxx  ',' yyy  ',' ....    ',' zzz  ',' 5     ',' 0     ',' 0     ',' 0     ',' 4     ',' 0     ',' 0     ' union all
select ' name Z ',' week2 ',' xxx  ',' yyy  ',' ....    ',' zzz  ',' 0     ',' 4     ',' 5     ',' 4     ',' 0     ',' 0     ',' 2     ' 
)
select * from t unpivot (dayVal for dayName in (day1, day2, day3, day4, day5, day6, day7)) t

有关使用 unpivot 的更多详细信息,请参阅microsoft documentation。

输出如下所示:

【讨论】:

这正是我所需要的,我正在尝试使用 pivot,但这更清楚【参考方案2】:

你签出PIVOT了吗?

@jarlh:表有字段。有时称为列,有时称为字段。

【讨论】:

在 SQL 世界中,表有列。 SQL 中的字段是别的东西,例如时间值的分钟字段。全部符合 ISO/ANSI SQL 标准。但是,Excel 用户可能对此有不同的想法。

以上是关于按某些列 SQL 旋转(转置)的主要内容,如果未能解决你的问题,请参考以下文章

ClickHouse 按列输出,而不是按行输出(实际上没有转置的转置?)

将列转置为行 SQL Server

从现有列转置 Hive SQL 数据

如何将行数据转置/旋转到 Spark Scala 中的列? [复制]

SQL 如何将数据转置和分组到静态列中? [复制]

如何以特定格式转置 SQL 中的表?