SQL - 按列对两行进行分组,不同列上的值和空值
SQL - Group two rows by columns that value and null on different columns
问题
假设我有一个 table 包含这样的行:
id | country | place | last_action | second_to_last_action
----------------------------------------------------------
1 | US | 2 | reply |
1 | US | 2 | | comment
4 | DE | 5 | reply |
4 | | | | comment
我想做的是将它们按 ID、国家和地点组合起来,这样 last_action 和 second_to_last_action 就会在同一行
id | country | place | last_action | second_to_last_action
----------------------------------------------------------
1 | US | 2 | reply | comment
4 | DE | 5 | reply | comment
我将如何处理这个问题?我想我在这里需要一个聚合,但我的脑子里一片空白,不知道我应该使用哪个。
可以预料,总会有一对相配的。
背景:
注意:这个 table 是从这样的东西派生出来的:
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
然后我通过获取 event_no 1 和 2 获得了最后一个和 second_to_last 操作。因此,如果有更有效的方法在两个不同的列中获取最后两个操作,我会很乐意听到了。
您可以使用聚合修复您的第一个数据:
select id, country, place, max(last_action), max(second_to_last_action)
from derived
group by id, country, place;
您可以使用条件聚合从原始 table 执行此操作:
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;
问题
假设我有一个 table 包含这样的行:
id | country | place | last_action | second_to_last_action
----------------------------------------------------------
1 | US | 2 | reply |
1 | US | 2 | | comment
4 | DE | 5 | reply |
4 | | | | comment
我想做的是将它们按 ID、国家和地点组合起来,这样 last_action 和 second_to_last_action 就会在同一行
id | country | place | last_action | second_to_last_action
----------------------------------------------------------
1 | US | 2 | reply | comment
4 | DE | 5 | reply | comment
我将如何处理这个问题?我想我在这里需要一个聚合,但我的脑子里一片空白,不知道我应该使用哪个。
可以预料,总会有一对相配的。
背景:
注意:这个 table 是从这样的东西派生出来的:
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
然后我通过获取 event_no 1 和 2 获得了最后一个和 second_to_last 操作。因此,如果有更有效的方法在两个不同的列中获取最后两个操作,我会很乐意听到了。
您可以使用聚合修复您的第一个数据:
select id, country, place, max(last_action), max(second_to_last_action)
from derived
group by id, country, place;
您可以使用条件聚合从原始 table 执行此操作:
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;