我正在学习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 |
| .... | .. |
+--------+--------+
正如您所看到的,对于每个名字,我想根据计数选择国家。
答案 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
min(nation)
- min在这种情况下毫无意义,但你必须保留它
(没有工作)keep
- 只保留nation
dense_rank last
说要拿起最后一个元素order by cnt
说明如何定义元素的顺序最终,每个名字都会成为最重要的国家。
可以达到同样的效果select name, min(nation) keep (dense_rank first order by cnt desc)