使用 CASE 将附加列组合成一行?

Posted

技术标签:

【中文标题】使用 CASE 将附加列组合成一行?【英文标题】:Combine into one row with additional columns using CASE? 【发布时间】:2020-08-26 17:27:39 【问题描述】:

例如,我有一张桌子,我们称之为就业:

ID        NAME         Employer           StartDate          EndDate
-----------------------------------------------------------------------
20        John         Company A          2-5-2015           5-5-2018
20        John         Company B          5-10-2018          NULL
100       Bill         Company C          10-10-2017         10-15-2018
100       Bill         Company D          11-20-2018         3-5-2019
100       Bill         Company E          4-5-2019           NULL

我要做的是构建一个包含以下列的报告:

ID         NAME        Employer1      Employer2         Employer3

例如,基于上表,我想展示:

ID         NAME        Employer1      Employer2         Employer3
-------------------------------------------------------------------
20         John        Company B      Company A         NULL
100        Bill        Company E      Company D         Company C

我希望 Employer1 列始终显示他们最近/当前的雇主,并从那里下降到 Employer2 和 Employer3 列。如果某人只有 1 个雇主,则 Employer2 和 Employer3 应为 NULL,如果他们只有 2 个雇主,则 Employer3 应为 NULL。

【问题讨论】:

为什么结果中 Bill 的 id = 50? 抱歉,这是我的错误,我现在已经更新了。 如果一个id超过3行怎么办? 如果超过 3 个,我想选择前 3 个,其中 Employer1 是最新/当前的,然后下降到 Employer2 和 Employer3 请向我们展示您的尝试。 【参考方案1】:

带有ROW_NUMBER()窗口功能:

select id, name,
       max(case when rn = 1 then employer end) Employer1,        
       max(case when rn = 2 then employer end) Employer2,
       max(case when rn = 3 then employer end) Employer3
from (
  select *, row_number() over (partition by id, name order by startdate desc) rn
  from employment
) e
group by id, name
order by id, name

请参阅demo。 结果:

>  id | name | Employer1 | Employer2 | Employer3
> --: | :--- | :-------- | :-------- | :--------
>  20 | John | Company B | Company A | null     
> 100 | Bill | Company E | Company D | Company C

【讨论】:

【参考方案2】:

我认为这样的事情会奏效。条件聚合

;with emp_rn_cte as (
    select e.*, row_number() over (partition by e.ID order by e.StartDate) rn from Employment e)
select ID, [NAME],
       max(iif(er.rn=1, er.Employer, null)) Employer1,
       max(iif(er.rn=2, er.Employer, null)) Employer2,
       max(iif(er.rn=3, er.Employer, null)) Employer3
from
  emp_rn_cte er
where er.rn<=3
group by ID, [NAME]
order by ID, [NAME];

【讨论】:

以上是关于使用 CASE 将附加列组合成一行?的主要内容,如果未能解决你的问题,请参考以下文章

MySql,将日期和时间列组合成时间戳

使用 PHP 将多个 SQL 列组合成 HTML 表的单个列

将 scala 数据框列组合成单个案例类

如何通过使用 R 将每个文件的数据添加为附加行来将不同的 .csv 文件组合成一个完整的文件?

pandas将dataframe数据列中的年月日列组合成单一的日期数据列实战

将一个表的连接列与另一个表的一列组合成 JAVA 对象