【问题标题】:Return row per key based on precedence in Oracle's SQL根据 Oracle 的 SQL 中的优先级返回每个键的行
【发布时间】:2021-11-10 13:04:28
【问题描述】:
我有如下数据。有些项目有不止一种类型的 id。
我只需要从每个 id 中选择一个。
我的条件是
- 如果存在(项目的类型 id == 1)只选择该行;
- 如果不存在类型 id 为 1 检查是否存在(项目的类型 id == 2)选择
该行;
- 如果不存在,则类型 id 为 2,检查是否存在(项目的类型 id == 3)
选择该行;
我不需要类型 id 不同于 1、2、3 的数据
| id |
name |
type_id |
| 23 |
xx |
1 |
| 24 |
yy |
1 |
| 24 |
yy |
2 |
| 24 |
yy |
3 |
| 25 |
zz |
2 |
| 26 |
qq |
2 |
| 26 |
qq |
3 |
| 27 |
ww |
null |
| 28 |
tt |
4 |
| 28 |
rr |
5 |
预期结果
| id |
name |
type_id |
| 23 |
xx |
1 |
| 24 |
yy |
1 |
| 25 |
zz |
2 |
| 26 |
qq |
2 |
【问题讨论】:
标签:
sql
oracle
greatest-n-per-group
【解决方案1】:
你可以使用row_number():
select t.*
from (select t.*,
row_number() over (partition by id order by type_id) as seqnum
from t
where type_id in (1, 2, 3)
) t
where seqnum = 1;
注意:这使用了您要查找的类型是有序的这一事实。如果它们是任意的,那么您可能需要order by 中的case 表达式。例如,如果您希望优先级为 2、1、3:
order by (case type_id when 2 then 1 when 1 then 2 when 3 then 3 end)
【解决方案2】:
select id,
min(name) keep (dense_rank first order by type_id) as name,
min(type_id) as type_id
from table_name
where type_id in (1, 2, 3)
group by id
;