首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Oracle/SQL -使用rank函数

Oracle/SQL -使用rank函数
EN

Stack Overflow用户
提问于 2011-09-13 05:57:09
回答 4查看 3.7K关注 0票数 0

我正在尝试做的是一个表中的人员列表,如果一个人不止一次存在,则返回包含最高排名的“代码”的记录。

代码排名(从高到低):T,E,F

因此,对于给定的数据集

代码语言:javascript
复制
Person  Code
----------------    
Tom     F
Paul    E
Mark    F
Paul    T
Mark    E
Chris   T
Chris   E

我将从我的查询中得到以下内容

代码语言:javascript
复制
Person  Code
----------------
Tom     F
Paul    T
Mark    E
Chris   T

我假设这将使用秩/解析函数,但我对它们还不够熟悉。

谢谢!

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2011-09-13 19:52:25

最短、最高性能且特定于Oracle的解决方案:

代码语言:javascript
复制
SQL> create table mytable(person,code)
  2  as
  3  select 'Tom', 'F' from dual union all
  4  select 'Paul', 'E' from dual union all
  5  select 'Mark', 'F' from dual union all
  6  select 'Paul', 'T' from dual union all
  7  select 'Mark', 'E' from dual union all
  8  select 'Chris', 'T' from dual union all
  9  select 'Chris', 'E' from dual
 10  /

Table created.

SQL> select person
  2       , max(code) keep (dense_rank first order by decode(code,'T',1,'E',2,'F',3,4)) code
  3    from mytable
  4   group by person
  5  /

PERSO C
----- -
Chris T
Mark  E
Paul  T
Tom   F

4 rows selected.

致以敬意,

罗伯。

票数 0
EN

Stack Overflow用户

发布于 2011-09-13 06:04:40

您可以使用RANK函数对数据进行排名

代码语言:javascript
复制
SQL> ed
Wrote file afiedt.buf

  1  with data as (
  2    select 'Tom' person, 'F' code from dual union all
  3    select 'Paul', 'E' from dual union all
  4    select 'Paul', 'T' from dual union all
  5    select 'Mark', 'F' from dual union all
  6    select 'Mark', 'E' from dual
  7  )
  8  select *
  9    from (select person,
 10                 code,
 11                 rank() over (partition by person
 12                                  order by (case when code='T' then 1
 13                                                 when code='E' then 2
 14                                                 when code='F' then 3
 15                                                 else null
 16                                             end)) rnk
 17*           from data)
SQL> /

PERS C        RNK
---- - ----------
Mark E          1
Mark F          2
Paul T          1
Paul E          2
Tom  F          1

Elapsed: 00:00:00.00

然后,您只需要选择RNK为1的行

代码语言:javascript
复制
SQL> ed
Wrote file afiedt.buf

  1  with data as (
  2    select 'Tom' person, 'F' code from dual union all
  3    select 'Paul', 'E' from dual union all
  4    select 'Paul', 'T' from dual union all
  5    select 'Mark', 'F' from dual union all
  6    select 'Mark', 'E' from dual
  7  )
  8  select *
  9    from (select person,
 10                 code,
 11                 rank() over (partition by person
 12                                  order by (case when code='T' then 1
 13                                                 when code='E' then 2
 14                                                 when code='F' then 3
 15                                                 else null
 16                                             end)) rnk
 17            from data)
 18*  where rnk = 1
SQL> /

PERS C        RNK
---- - ----------
Mark E          1
Paul T          1
Tom  F          1

Elapsed: 00:00:00.00
票数 2
EN

Stack Overflow用户

发布于 2011-09-13 06:00:22

我不认为你需要的是等级...

基本上,您的删除将如下所示:(伪查询)

代码语言:javascript
复制
delete the rows from person
where that row is not in ( select the rows from person with the highest code )

编辑

这个技巧也可能对你有帮助:

代码语言:javascript
复制
select person, code, decode( code, 'T', 1, 'E', 2, 'F', 3, 0 ) from mytable
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/7394535

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档