Oracleクエリで複数のグループのN個の結果を取得するにはどうすればよいですか。
たとえば、次の表があるとします。
|--------+------------+------------|
| emp_id | name | occupation |
|--------+------------+------------|
| 1 | John Smith | Accountant |
| 2 | Jane Doe | Engineer |
| 3 | Jack Black | Funnyman |
|--------+------------+------------|
より多くの職業を持つより多くの行があります。それぞれの職業から3人の従業員(言うまでもなく)を取得したいと思います。
サブクエリを使用せずにこれを行う方法はありますか?
これにより、必要なものが生成され、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人の従業員を示しています。不等式の比較で使用される属性を変更して、上位の従業員に名前などで指定することができます。
現在、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
RowNumをランクに追加します:
select * from
(select emp_id, name, occupation,rank() over ( partition by occupation order by emp_id,RowNum) rank
from employee)
where rank <= 3
これが非常に効率的かどうかはわかりませんが、おそらく出発点ですか?
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人の異なる従業員を含む行が表示されます。残念ながら、それはあなたにそれらのすべての組み合わせを与えるでしょう。
誰かがこれを減らしてくれませんか?
これをSQLServerでテストしました(サブクエリを使用します)
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)
ニーズに合わせてサブクエリでORDERbyを実行するだけです