16

Oracle クエリで複数のグループに対して N 個の結果を取得するにはどうすればよいでしょうか。

たとえば、次の表があるとします。

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

より多くの職業を持つさらに多くの行があります。各職業から 3 人の従業員 (たとえば) を取得したいと考えています。

サブクエリを使わずにこれを行う方法はありますか?

4

5 に答える 5

41

私は今手元に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

于 2008-09-25T18:27:48.760 に答える
14

これにより、必要なものが生成され、TOP N や RANK() などのベンダー固有の SQL 機能は使用されません。

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_id 値が最も低い 3 人の従業員が示されます。不等式比較で使用される属性を変更して、上位の従業員に名前を付けたり、その他のことを行うことができます。

于 2008-09-25T20:48:29.903 に答える
3

RowNum を rank に追加します。

select * from 
         (select emp_id, name, occupation,rank() over ( partition by occupation order by emp_id,RowNum) rank   
                      from employee) 
         where rank <= 3 
于 2011-06-07T10:05:12.793 に答える
1

これが非常に効率的かどうかはわかりませんが、おそらく出発点ですか?

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 人の異なる従業員を含む行が得られるはずです。残念ながら、それらのすべての組み合わせが得られます。

誰でもこれを削減できますか?

于 2008-09-25T18:24:55.007 に答える
1

これを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 を実行するだけです

于 2008-09-25T18:32:12.150 に答える