给定一个表,例如
id | 名字 | 城市 | 优先 | 更新了 |
---|---|---|---|---|
1 | 以撒 | 火星 | 1 | 时间戳 |
2 | 阿西莫夫 | 巴黎 | 0 | 时间戳 |
3 | 杰克 | 纽约 | 1 | 时间戳 |
我想获取多个项目,每个城市/名称组合 1 个,并确定优先级/确保具有优先级的行包含在结果中。处理优先级后,将选择“最旧”的行
例如,在上表中,如果我们获取 2 行,则预计会获取 id 1 和 3。如果我们获取 3 行而不是 2 行,那么 id 2 也会被包含在内(我们首先获取优先行,如果有空间,则填写非优先行)
我正在尝试像这样的查询
select any_value(id) keep(dense_rank first order by priority, updated) from table group by city, name fetch next 2 rows only
但在优先级方面遇到麻烦。一种可能的解决方案可能是连接两个不同的选择,一个获取优先级行,一个获取非优先级(给定带宽),但这似乎是相当复杂且低效的方法,并且随着数据库的增长可能无法很好地扩展
尝试了一下,结果是这样的:
with prioritized as (select id, city, name from table where priority = 1)
select id from prioritized
UNION ALL -- UNION alone sorts the output
select distinct first_value(id) over (partition by name, city order by updated asc)
from table
where priority = 0
and (city, name) not in (select city, name from prioritized)
我用 SQLite 尝试过这个,但我认为这也符合 oracle 语法。 通常,Oracle 非常擅长优化此类查询,但在尝试应用魔法之前,您可以检查这是否符合您的要求,以及解释计划是否使优化看起来是必要的