sql-将两行按不同列上的value和null列分组

xeufq47z  于 2021-07-24  发布在  Java
关注(0)|答案(1)|浏览(409)

问题

假设我有一个这样行的表:

id | country | place | last_action | second_to_last_action
----------------------------------------------------------
1  |   US    |   2   |   reply     | 
1  |   US    |   2   |             |       comment
4  |   DE    |   5   |   reply     | 
4  |         |       |             |       comment

我要做的是将这些按id、国家和地点进行组合,以便最后一个\u操作和第二个\u到\u最后一个\u操作位于同一行

id | country | place | last_action | second_to_last_action
----------------------------------------------------------
1  |   US    |   2   |   reply     |      comment
4  |   DE    |   5   |   reply     |      comment

我该怎么做?我想我需要一个聚合在这里,但我的头脑是完全空白,我应该用哪一个。
可以预期,总会有一对匹配的。

背景:

注:此表源自以下内容:

id | country | place |   action    | time
----------------------------------------------------------
1  |   US    |   2   |   reply     |    16:15
1  |   US    |   2   |   comment   |    15:16
1  |   US    |   2   |   view      |    13:16
4  |   DE    |   5   |   reply     |    17:15
4  |   DE    |   5   |   comment   |    16:16
4  |   DE    |   5   |   view      |    14:12

用于分区的代码是:

row_number() over (partition by id order by time desc) as event_no

然后我得到了最后一个和第二个到最后一个动作,得到了事件1和2。因此,如果有更有效的方法将最后两个动作放在两个不同的列中,我会很高兴听到这样的消息。

bq8i3lrv

bq8i3lrv1#

您可以使用聚合修复第一个数据:

select id, country, place, max(last_action), max(second_to_last_action)
from derived
group by id, country, place;

可以使用条件聚合从原始表执行此操作:

select id, country, place,
       max(case when seqnum = 1 then action end) as last_action,
       max(case when seqnum = 2 then action end) as second_to_last_action
from (select t.*,
            row_number() over (partition by id order by time desc) as seqnum
      from t
     ) t
group by id, country, place;

相关问题