【问题标题】:How to query the three best players in Oracle?如何查询Oracle中最好的三个玩家?
【发布时间】:2014-12-12 11:22:22
【问题描述】:

我有下表:

姓名 |分数 爱丽丝 | 100 鲍勃 | 90 查尔斯| 90 公爵 | 80 前夕 | 70 ...

我的问题如下:

如何一键提取三名最佳球员的名字?在我的示例中,查询应该返回 行(ALICE、BOB、CHARLES 和 DUKE),因为有两个银牌得主(他们都有 90 分)。

提前谢谢你。

【问题讨论】:

  • 除非这是家庭作业,否则在现实世界中我会处理代码中多余的行并继续前进。
  • @tgkprog 如果只需要 3 行,为什么还要查询和处理 10000 行?
  • 我认为问题在于你只想要 3 行但得到 4 行。所以我的意思是多得到一个并在代码中丢弃它。但我现在明白你的意思了。在我的 sql 中更容易:)

标签: sql oracle


【解决方案1】:

Oracle 有DENSE_RANK 分析函数用于该目的:

select name, score from (
  select name, score, dense_rank() over(order by score desc nulls last) rank
  --                                                        ^^^^^^^^^^
  --                                                 reject NULL score at the end
  from t
) V
where rank < 4
order by rank, name

http://sqlfiddle.com/#!4/88445/5

【讨论】:

  • 不错的解决方案。我喜欢。它比 beny23 的解决方案(也有效)更具可读性。另一方面,如果有一条记录为空分数,那么该行将是第一行。当然可以使用 nvl 函数或 nulls last 修饰符的顺序来处理。
  • @László 我已编辑我的答案以在 ORDER BY 子句中使用 NULLS LAST 说明符。这应该可以优雅地处理 NULL 分数问题。
【解决方案2】:

下面怎么样

select * 
  from table1
 where score >=
   (select score from (
     select score, rownum r from (
      select distinct score from table1 order by score desc
     ) where rownum <= 3
   ) where r = 3)
order by score desc

另请参阅此 SQLFiddle:http://sqlfiddle.com/#!4/23e68/1

【讨论】:

  • 谢谢。好像没问题。找到一个子查询更少的解决方案会很好。
  • 请注意,带有 rownum 的嵌套子查询是一种 Oracle 模式,并且它非常高效(取决于您定义的索引),因此虽然它看起来很复杂,但它相当高效。
  • 你可能会觉得我提这个很愚蠢,但我发现同样需要。当 Score 是 VARCHAR2 时,ORDER BY DESC 会失败,因为最后是 100。但在一些实际应用程序中(从前端获取某些业务逻辑后获取价值),数据可能也在需要解析的 VARCHAR2 中。所以只是想让你看看。小提琴:sqlfiddle.com/#!4/2a4b0/1
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-08-04
  • 1970-01-01
  • 2022-01-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多