代码之家  ›  专栏  ›  技术社区  ›  oneself

获取每组的最佳结果(在Oracle中)

  •  10
  • oneself  · 技术社区  · 16 年前

    我怎样才能得到几个组的n个结果 Oracle查询。

    例如,给出下表:

    |--------+------------+------------|
    | emp_id | name       | occupation |
    |--------+------------+------------|
    |      1 | John Smith | Accountant |
    |      2 | Jane Doe   | Engineer   |
    |      3 | Jack Black | Funnyman   |
    |--------+------------+------------|
    

    有更多的排,有更多的职业。我想买 每个职业有三名员工。

    有没有一种不用子查询就可以做到这一点的方法?

    5 回复  |  直到 6 年前
        1
  •  11
  •   Bill Karwin    6 年前

    这将生成您想要的,并且它不使用特定于供应商的SQL功能,如top n或rank()。

    SELECT MAX(e.name) AS name, MAX(e.occupation) AS occupation 
    FROM emp e 
      LEFT OUTER JOIN emp e2 
        ON (e.occupation = e2.occupation AND e.emp_id <= e2.emp_id) 
    GROUP BY e.emp_id 
    HAVING COUNT(*) <= 3 
    ORDER BY occupation;
    

    在这个例子中,它给出了每个职业的EMP值最低的三个雇员。您可以更改不平等比较中使用的属性,使其按姓名或其他方式给顶级员工。

        2
  •  33
  •   John Siracusa    14 年前

    我现在手头没有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

        3
  •  2
  •   Andrei Sfat systemfreund    13 年前

    将rownum添加到排名:

    select * from 
             (select emp_id, name, occupation,rank() over ( partition by occupation order by emp_id,RowNum) rank   
                          from employee) 
             where rank <= 3 
    
        4
  •  1
  •   dugas    12 年前

    在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)
    

    只需在子查询中按顺序排序即可满足您的需要

        5
  •  1
  •   default locale    10 年前

    我不确定这是不是很有效率,但也许是个起点?

    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个不同雇员的行,所有雇员都在同一职业中。不幸的是,它会给你所有这些的组合。

    有人能把这个减掉吗?