2008-09-25 66 views
7

如何才能在 的oracle查詢中獲得多個組的N個結果。獲取每個組的最佳結果(在Oracle中)

例如,下表給出:

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

還有更多的行與更多的職業。我想得到 三名僱員(讓我們說)從每個職業。

有沒有辦法做到這一點,而不使用子查詢?

回答

11

這產生你想要的東西,並且它不使用供應商特定的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值的三名僱員。您可以更改在不平等比較中使用的屬性,以便通過名稱或其他方式給予頂級員工。

2

我不確定這是非常有效的,但也許是一個起始的地方?

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個不同的僱員都在同一職業的行。不幸的是,它會給你所有這些組合。

任何人都可以削減這一點嗎?

28

我沒有一個Oracle實例方便所以我現在還沒有測試過這一點:

select * 
from (select emp_id, name, occupation, 
     rank() over (partition by occupation order by emp_id) rank 
     from employee) 
where rank <= 3 

這裏是排名如何工作的一個環節:在SQL Server http://www.psoug.org/reference/rank.html

+2

Didnt他沒有指定一個子查詢......? – AviD 2008-09-25 19:26:46

+1

是的,但他可能意味着「不使用再次從同一表中選擇的子查詢」。該解決方案使用子查詢,但只訪問表一次。 – 2008-09-26 10:32:57

2

測試這(和它使用子查詢)

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的子查詢,以滿足您的需求

2

添加ROWNUM排名:

select * from 
     (select emp_id, name, occupation,rank() over (partition by occupation order by emp_id,RowNum) rank 
         from employee) 
     where rank <= 3 
相關問題