带有 MIN() 和多列的 SQL PIVOT 表

Posted

技术标签:

【中文标题】带有 MIN() 和多列的 SQL PIVOT 表【英文标题】:SQL PIVOT table with MIN() and on Multiple columns 【发布时间】:2018-11-15 17:17:13 【问题描述】:

这是表结构

ID          TypeX   TypeXDesc           XDate       TypeCodeY
040001      3669    Unspecified Cat    2005-08-08   1
040001      3669    Unspecified Cat    2006-08-29   2
040001      37515   Tear Film          2005-08-08   1
040001      37999   Disor              2004-07-22   1

使用 PIVOT 将上面的表格转换为下面的表格

ID          TypeX_1 TypeXDesc_1         XDate_1     TypeCodeY_1     TypeX_2 TypeXDesc_2         XDate_2     TypeCodeY_2     TypeX_3 TypeXDesc_3 XDate_3     TypeCodeY_3
040001      3669    Unspecified Cat    2005-08-08   1               37515   Tear Film          2005-08-08   1               37999   Disor       2004-07-22  1

查看相同的 TypeX 代码,但 XDate 不同,我们需要获取 Min(XDate),因此第一行是限定的,而不是第二行。

【问题讨论】:

请提供任何 cmet,小线索会让我继续前进.. 放弃尝试使用 PIVOT 运算符并使用聚合大小写表达式。 我从聚合的 case 表达式开始,但运行查询的时间很长,有人建议我使用 PIVOT。还有 20 列 TypeX_1,2,3...20,使用聚合案例 exp 变得越来越昂贵 PIVOT 语法不会更好。事实上,聚合的 CASE 通常会胜过 PIVOT。 【参考方案1】:

您可以使用条件聚合来完成此操作。在这种情况下,您可以使用row_number() 枚举typex/id 组内的行。您可以使用typex/id 使用dense_rank() 枚举组。

然后,使用条件聚合:

select t.id,
       max(case when grpnum = 1 and seqnum = 1 then typex end) as typex_1,
       max(case when grpnum = 1 and seqnum = 1 then TypeXDesc end) as TypeXDesc_1,
       max(case when grpnum = 1 and seqnum = 1 then XDate end) as XDate_1,
       max(case when grpnum = 1 and seqnum = 1 then TypeCodeY end) as TypeCodeY_1,
       max(case when grpnum = 2 and seqnum = 1 then typex end) as typex_12,
       max(case when grpnum = 2 and seqnum = 1 then TypeXDesc end) as TypeXDesc_2,
       max(case when grpnum = 2 and seqnum = 1 then XDate end) as XDate_2,
       max(case when grpnum = 2 and seqnum = 1 then TypeCodeY end) as TypeCodeY_3,
       max(case when grpnum = 3 and seqnum = 1 then typex end) as typex_1,
       max(case when grpnum = 3 and seqnum = 1 then TypeXDesc end) as TypeXDesc_3,
       max(case when grpnum = 3 and seqnum = 1 then XDate end) as XDate_3,
       max(case when grpnum = 3 and seqnum = 1 then TypeCodeY end) as TypeCodeY_3
from (select t.*,
             row_number() over (partition by id, typex order by xdate as seqnum,
             dense_rank() over (partition by id order by typex) as grpnum
     from t
    ) t
group by id;

【讨论】:

以上是关于带有 MIN() 和多列的 SQL PIVOT 表的主要内容,如果未能解决你的问题,请参考以下文章

如何在sql中使用pivot到多列

SQL Pivot 多列 [关闭]

具有多列日期的 SQL Server 数据透视表

MS SQL Pivot 来自多列的长数据

带有重复变量的sql pivot

在 SQL Pivot 上使用 Min 聚合