获得每个组的最佳结果(在Oracle中)
时间:2020-03-06 14:44:20 来源:igfitidea点击:
我如何才能获得N个针对几个小组的结果
一个oracle查询。
例如,给定下表:
|--------+------------+------------| | emp_id | name | occupation | |--------+------------+------------| | 1 | John Smith | Accountant | | 2 | Jane Doe | Engineer | | 3 | Hyman Black | Funnyman | |--------+------------+------------|
有更多行和更多职业。我想得到
每个职业有三名员工(可以说)。
有没有不使用子查询来执行此操作的方法?
解决方案
我不确定这是否非常有效,但也许是一个起点?
select * from people p1 join people p2 on p1.occupation = p2.occupation join people p3 on p1.occupation = p3.occupation and p2.occupation = p3.occupation where p1.emp_id != p2.emp_id and p1.emp_id != p3.emp_id
这应该为我们提供包含3个不同雇员的行,这些雇员全部处于同一职业。不幸的是,它将为我们提供所有这些组合。
任何人都可以减少这个吗?
我现在没有手头的oracle实例,因此我没有对此进行测试:
select * from (select emp_id, name, occupation, rank() over ( partition by occupation order by emp_id) rank from employee) where rank <= 3
这是有关排名如何工作的链接:http://www.psoug.org/reference/rank.html
在SQL Server中对此进行了测试(它使用了子查询)
select emp_id, name, occupation from employees t1 where emp_id IN (select top 3 emp_id from employees t2 where t2.occupation = t1.occupation)
只需在子查询中执行ORDER by即可满足需求
这将产生所需的内容,并且不使用供应商特定的SQL功能(例如TOP N或者RANK())。
SELECT e.name, e.occupation FROM emp AS e LEFT OUTER JOIN emp AS e2 ON (e.occupation = e2.occupation AND e.emp_id <= e2.emp_id) GROUP BY e.emp_id HAVING COUNT(*) <= 3 ORDER BY e.occupation;
在此示例中,它为三名雇员提供每个职业emp_id最低的值。我们可以更改不等式比较中使用的属性,以使其按名称或者其他方式赋予高层雇员。