これは、分析関数を使用して簡単に解決できます。ご覧のとおり、DEPT20で最大給与を獲得している従業員は2人です。この種の問題に対するいくつかの一般的な解決策はその情報を見逃しているため、これは重要な詳細です。
SQL> select ename
2 , deptno
3 , sal
4 from (
5 select ename
6 , deptno
7 , sal
8 , max (sal) over (partition by deptno) max_sal
9 , min (sal) over (partition by deptno) min_sal
10 from emp
11 )
12 where sal = max_sal
13 or sal = min_sal
14 order by deptno, sal
15 /
ENAME DEPTNO SAL
---------- ---------- ----------
KISHORE 10 1300
SCHNEIDER 10 5000
CLARKE 20 800
RIGBY 20 3000
GASPAROTTO 20 3000
HALL 30 950
LIRA 30 3750
TRICHLER 50 3500
FEUERSTEIN 50 4500
9 rows selected.
SQL>
おっと、結果の形式に関する重要な詳細を見逃しました。最大給与を稼いでいる従業員が2人いるため、私のデータは要求された出力に適合しません。したがって、私が認めるこのクエリは少し厄介で、必要なレイアウトを提供します。従業員名のMIN()はアルファベット順を返します:
SQL> select
2 deptno
3 , max (case when sal = min_sal then min_sal else null end ) as min_sal
4 , min (case when sal = min_sal then ename else null end ) as min_name
5 , max (case when sal = max_sal then max_sal else null end ) as max_sal
6 , min (case when sal = max_sal then ename else null end ) as max_name
7 from (
8 select ename
9 , deptno
10 , sal
11 , max (sal) over (partition by deptno) max_sal
12 , min (sal) over (partition by deptno) min_sal
13 from emp
14 )
15 where sal = max_sal
16 or sal = min_sal
17 group by deptno
18 order by deptno
19 /
DEPTNO MIN_SAL MIN_NAME MAX_SAL MAX_NAME
---------- ---------- ---------- ---------- ----------
10 1300 KISHORE 5000 SCHNEIDER
20 800 CLARKE 3000 GASPAROTTO
30 950 HALL 3750 LIRA
50 3500 TRICHLER 4500 FEUERSTEIN
SQL>
私はこの解決策が好きではありません。ほとんどのデータセットにはそのような衝突が含まれているため、それらを確認する必要があります。プロクラステスのレポートレイアウトに合うようにいくつかの無関係な基準に基づいて結果をフィルタリングすることは誤解を招く恐れがあります。データセット全体を反映したレポートレイアウトをお勧めします。最終的には、クエリが提供するビジネス目的によって異なります。そしてもちろん、顧客は常に正しいです8-)