PostgreSQL合并行:按organization_core_id聚合并取非空最新值
PostgreSQL按organization_core_id合并行并保留最新非空值的实现方案
嘿,这事儿我熟!要实现按organization_core_id合并行,同时用每个字段的最新非空值填充对应列,咱们可以结合窗口函数来搞定。首先得明确:这里的“最新”一般是基于表中的时间戳字段(比如updated_at)或者自增主键(比如id)来判断,我下面就以常见的updated_at时间戳为例来写方案~
假设你的原始表名为your_org_table,包含字段organization_core_id、slug、name、updated_at,可以用下面的SQL语句实现需求:
WITH ranked_orgs AS ( SELECT organization_core_id, -- 取当前分组下最新的非空slug FIRST_VALUE(slug) OVER ( PARTITION BY organization_core_id ORDER BY CASE WHEN slug IS NOT NULL THEN updated_at ELSE '1970-01-01' END DESC ) AS slug, -- 取当前分组下最新的非空name FIRST_VALUE(name) OVER ( PARTITION BY organization_core_id ORDER BY CASE WHEN name IS NOT NULL THEN updated_at ELSE '1970-01-01' END DESC ) AS name, -- 给每个分组的记录按时间降序排名,方便后续去重 ROW_NUMBER() OVER (PARTITION BY organization_core_id ORDER BY updated_at DESC) AS row_rank FROM your_org_table ) -- 每个organization_core_id只保留一行结果 SELECT organization_core_id, slug, name FROM ranked_orgs WHERE row_rank = 1 GROUP BY organization_core_id, slug, name;
代码解释:
- CTE
ranked_orgs:这里做了两件核心事:- 用
PARTITION BY organization_core_id把数据按目标字段分组; - 针对
slug和name分别用FIRST_VALUE()窗口函数,排序时通过CASE语句优先把非空值的记录按updated_at降序排列,这样最新的非空值就会被选为FIRST_VALUE的结果; - 用
ROW_NUMBER()给每个分组内的记录按时间降序排名,确保后续能筛选出唯一的合并行。
- 用
- 外层查询:通过
row_rank = 1筛选出每个分组的第一条记录,再通过GROUP BY去重(避免分组内多条记录导致的重复结果),最终得到你想要的合并格式。
特殊情况调整:
如果你的表没有updated_at字段,而是用自增主键id来判断“最新”,只需要把ORDER BY里的updated_at换成id就行,比如:
ORDER BY CASE WHEN slug IS NOT NULL THEN id ELSE 0 END DESC
如果某个字段在该分组的所有记录中都是空值,结果里对应的字段也会是空,这是符合逻辑的~
内容的提问来源于stack exchange,提问作者ThomasReggi
相关产品推荐
相关产品推荐

