如何获得Oracle中不同记录的最高排名?

时间:2012-12-04 18:21:39

标签: sql oracle count distinct

我有一个包含大量记录的表,其中一些字段是重复的。我想要每个重复中最常见的。

所以,如果我的表有如下数据:

 ID     Field1     Field2  
  1      A          10  
  2      A          12 
  3      B          5  
  4      A          10  
  5      B          5  
  6      A          10  
  7      B          8
  8      B          5
  9      A          10

我可以选择不同并获得计数:

select distinct Field1, Field2, count(Field1)
from Table
group by Field1, Field2
order by Field1, count(Field1) desc

这会给我

Field1    Field2     Count
A         10         4
A         12         1
B          5         3
B          8         1

但是,我只想要每个Field1的记录数最多。我一直在使用rank()而不是分区和子查询,但是没有找到使用两个字段表示唯一性并按计数选择最高记录的正确语法。我一直在寻找,我确信这已被问到,但我找不到它。

我希望得到以下内容

Field1     Field2       (optional) Count 
 A          10           4
 B           5           3

目标是查看一个只有一点不正确数据的表(在field1和field2之间链接错误),并根据它通常的内容确定它应该是什么。我不知道有多少不良记录,所以将Count低于某个阈值会有效,但看起来有点笨拙。

如果它更好,我可以创建一个临时表,将我的不同值放入,然后从那里选择,但似乎不应该这样。

3 个答案:

答案 0 :(得分:6)

我认为这就是你要找的东西:

select field1, field2, cnt from 
(select field1, field2, cnt, rank() over (partition by field1 order by cnt desc) rnk
from (select distinct Field1, Field2, count(Field1) cnt
            from Table1
            group by Field1, Field2
            order by Field1, count(Field1) desc) 
)
where rnk = 1;

SQL小提琴:http://sqlfiddle.com/#!4/fe96d/3

答案 1 :(得分:2)

由于多层嵌套子查询,它有点不优雅。但是它应该是合理有效的。遵循SQL

中的步骤应该相当容易
SQL> ed
Wrote file afiedt.buf

  1  with x as (
  2    select 1 id, 'A' field1, 10 field2 from dual union all
  3    select 2, 'A', 12 from dual union all
  4    select 3, 'B', 5 from dual union all
  5    select 4, 'A', 10 from dual union all
  6    select 5, 'B', 5 from dual union all
  7    select 6, 'A', 10 from dual union all
  8    select 7, 'B', 8 from dual union all
  9    select 8, 'B', 5 from dual union all
 10    select 9, 'A', 10 from dual
 11  )
 12  select field1,
 13         field2,
 14         cnt
 15    from (select field1,
 16                 field2,
 17                 cnt,
 18                 rank() over (partition by field1
 19                                  order by cnt desc) rnk
 20           from (select field1, field2, count(*) cnt
 21                   from x
 22                  group by field1, field2))
 23*  where rnk = 1
SQL> /

F     FIELD2        CNT
- ---------- ----------
A         10          4
B          5          3

答案 2 :(得分:2)

第三种方法;)

select field1,
       field2,
       max_cnt
from (
  select field1, 
         field2, 
         cnt,
         max(cnt) over (partition by field1, field2) as max_cnt,
         row_number() over (partition by field1 order by cnt desc) as rn
  from (
      select field1, 
             field2, 
             count(*) over (partition by Field1, Field2) as cnt
      from idlist
  ) t1 
) t2
where max_cnt = cnt 
and rn = 1

SQLFiddle:http://sqlfiddle.com/#!4/8461f/1