2つの理由から、Rank()関数はこれを実現する方法ではないと思います。
まず、Min()ベースのメソッドよりも効率が悪い可能性があります。
これは、クエリがデータをスキャンするときに部門ごとのすべての給与の順序付きリストを維持する必要があり、後でこのリストを再度読み取ることでランクが割り当てられるためです。明らかに、これに利用できるインデックスがない場合、最後のデータ項目が読み取られるまでランクを割り当てることができず、リストの保守に費用がかかります。
したがって、Rank()関数のパフォーマンスは、スキャンする要素の総数に依存します。ソートがディスクに流出するのに十分な数の場合、パフォーマンスは低下します。
これはおそらくより効率的です:
select dept,
emp,
salary
from
(
SELECT dept,
emp,
salary,
Min(salary) Over (Partition By dept) min_salary
FROM mytable
)
where salary = min_salary
/
この方法では、クエリがこれまでに遭遇した最小値の部門ごとに1つの値を維持する必要があるだけです。新しい最小値が検出されると、既存の値が変更されます。それ以外の場合、新しい値は破棄されます。メモリに保持する必要のある要素の総数は、スキャンされた行の数ではなく、部門の数に関連しています。
この場合、ランクを実際に計算する必要がないことを認識するためのコードパスがOracleにある可能性がありますが、私はそれには賭けません。
Rank()を嫌う2つ目の理由は、間違った質問に答えるだけだからです。問題は、「部門ごとの給与が昇順の場合に最初にランク付けされる給与を持つレコード」ではなく、「部門ごとの最低給与を持つレコード」です。少なくとも、それは私にとって大きな違いになります。