使用列的最大值从oracle sql表中过滤行

时间:2014-03-05 14:55:53

标签: sql oracle max inline-view

我正在学习oracle SQL,我有一个如下表:

+--------+--------+------------------------+
| name   | nation | count                  |
+--------+--------+------------------------+
| Ruben  | UK     | 2                      |
| Ruben  | EEUU   | 16                     |
| Cesar  | UK     | 21                     |
| Cesar  | EEUU   | 12                     |
| Cesar  | FRANCE | 4                      |
| John   | FRANCE | 3                      |
| John   | UK     | 7                      |
| ....   | ..     | ..                     |
+--------+--------+------------------------+

上表代表我使用查询创建的内联视图。正如您所看到的,表格按名称和国家分组,并进行一些计数。我想使用count列过滤表格,如下所示:

+--------+--------+
| name   | nation |
+--------+--------+
| Ruben  | EEUU   |
| Cesar  | UK     |
| John   | UK     |
| ....   | ..     |
+--------+--------+  

正如您所看到的,对于每个名字,我想根据计数选择国家。

2 个答案:

答案 0 :(得分:3)

您可以使用其他级别的内部查询执行此操作。类似的东西:

select name, nation
from (
  select name, nation, cnt,
    row_number() over (partition by name, nation order by cnt desc) as rn
  from (
    select name, nation, count(*) as cnt
    from <your table>
  )
)
where rn = 1;

row_number()分析为最内层查询添加一个伪列,对每个名称/国家/地区排名最高计数为1的行;然后,最外面的查询只查看排名第一的那些。

您需要决定如何处理关系 - 如果两个国家/地区名称行具有相同的计数,您可以使用rank()而不是row_number()来显示这两者。或者你可以通过在order by子句中添加另一列来决定选择哪一个。目前,如果有两个相同,它只会显示其中一个 - 它显示的是相当随意的。

答案 1 :(得分:3)

使用keep分析关键字:

select name, min(nation) keep (dense_rank last order by cnt)
from (select name, nation, count(*) as cnt
      from /* your data source */
      group by name, nation)
group by name
  1. min(nation) - min在这种情况下毫无意义,但你必须保留它 (没有工作)
  2. keep - 只保留nation
  3. 的一个结果
  4. dense_rank last说要拿起最后一个元素
  5. order by cnt说明如何定义元素的顺序
  6. 最终,每个名字都会成为最重要的国家。

    可以达到同样的效果
    select name, min(nation) keep (dense_rank first order by cnt desc)