需要 PIVOT 或 CASE 解决方案来将列转换为行(如果可能,非动态)

Posted

技术标签:

【中文标题】需要 PIVOT 或 CASE 解决方案来将列转换为行(如果可能,非动态)【英文标题】:Need PIVOT or CASE solution for converting columns to rows (NON-Dynamic if possible) 【发布时间】:2015-09-02 19:09:17 【问题描述】:

所以我有一个包含如下数据的表:

 SCHD_ID | INST_ID |
|---------|---------|
|    1001 |    Mike |
|    1001 |     Ted |
|    1001 |   Chris |
|    1002 |    Jill |
|    1002 |   Jamie |
|    1003 |    Brad |
|    1003 |    Carl |
|    1003 |    Drew |
|    1003 |    Nick |

我需要提出一个查询来显示如下数据:

|SCHD_ID  | INST 1 | INST 2 | INST 3 |
|---------|--------|--------|--------|
| 1001    | Mike   | Ted    | Chris  |
| 1002    | Jill   | Jamie  | Null   |
| 1003    | Brad   | Carl   | Drew   |

我已尝试查看所有枢轴描述和一些案例示例,但所有内容似乎都使用一个常见的重复值来进行枢轴旋转。这是列需要动态的情况之一,但仅限于某一点。在第三位讲师之后,我可以放弃任何数据。在上面的示例中,我没有为 SCHD_ID 1003 输入 INST 4 的列,即使在我的数据集示例中它存在。加入这样的约束是否可以为枢轴/案例语句提出非动态解决方案?

感谢您的帮助, 道恩

【问题讨论】:

【参考方案1】:

您可以使用row_number() 和条件聚合来做到这一点。但是,您的数据没有排序列,因此您无法保证您将获得哪三位讲师:

select schd_id,
       max(case when seqnum = 1 then inst_id end) as inst1,
       max(case when seqnum = 2 then inst_id end) as inst2,
       max(case when seqnum = 3 then inst_id end) as inst3
from (select t.*,
             row_number() over (partition by schd_id order by sched_id) as seqnum
      from table t
     ) t
group by SCHD_ID ;

如果您有选择讲师的优先顺序,则将逻辑放在order by 子句中。

【讨论】:

以上是关于需要 PIVOT 或 CASE 解决方案来将列转换为行(如果可能,非动态)的主要内容,如果未能解决你的问题,请参考以下文章

SQL Server中行列转换 Pivot UnPivot

使用pivot SQL将列转换为行

如何用Pivot实现行列转换

SQL 查询将列转换为行

死磕:SQL行转列汇总(全网最全最详细)

oracle 10g如何将列转换为行