基于year/month/name合并SQL记录,优先保留flag=Yes的行
问题:合并重复分组记录并优先保留flag为Yes的行
我有一张包含5列的表table1,为确保无重复记录,编写了如下SQL语句:
select flag, year, month, name, max(description) description from table1 group by flag, year, month, name order by year
执行后得到以下结果:
| flag | year | month | name | description |
|---|---|---|---|---|
| No | 2017 | 2 | name1 | random description11 |
| Yes | 2017 | 2 | name1 | random description112 |
| No | 2018 | 7 | name4 | random description44 |
| Yes | 2022 | 4 | name8 | random description999 |
| No | 2022 | 4 | name8 | random description999 |
需求
需要将结果合并为3条记录:
- 第1、2条记录
year、month、name相同,合并为一条并保留flag为Yes的行 - 第3条为唯一记录,直接保留
- 第4、5条记录
year、month、name相同,合并为一条并保留flag为Yes的行
期望结果
| flag | year | month | name | description |
|---|---|---|---|---|
| Yes | 2017 | 2 | name1 | random description112 |
| No | 2018 | 7 | name4 | random description44 |
| Yes | 2022 | 4 | name8 | random description999 |
解决方案
可以使用窗口函数ROW_NUMBER()实现需求,通过分组排序优先标记flag=Yes的记录,再筛选每组的第一条:
WITH ranked_data AS ( SELECT flag, year, month, name, description, -- 按year/month/name分组,flag=Yes的行号设为1,No设为2 ROW_NUMBER() OVER ( PARTITION BY year, month, name ORDER BY CASE WHEN flag = 'Yes' THEN 1 ELSE 2 END ) AS rn FROM table1 ) SELECT flag, year, month, name, description FROM ranked_data WHERE rn = 1 ORDER BY year;
逻辑说明
PARTITION BY year, month, name:将数据按year、month、name分组,确保相同组合的记录在同一组内ORDER BY CASE WHEN flag = 'Yes' THEN 1 ELSE 2 END:在每个分组内,给flag=Yes的行分配行号1,flag=No的行分配行号2,保证Yes的行优先级更高- 筛选
rn=1的记录,即可得到每组中符合要求的唯一行,满足合并需求
内容的提问来源于stack exchange,提问作者user1924249
相关产品推荐
相关产品推荐

