Je pense que la fonction Rank() n'est pas la bonne solution, pour deux raisons. Tout d'abord, il est probablement moins efficace qu'une méthode basée sur Min().
La raison en est que la requête doit maintenir une liste ordonnée de tous les salaires par département lors de l'analyse des données, et le classement sera ensuite attribué plus tard en relisant cette liste. Évidemment, en l'absence d'index qui peuvent être utilisés pour cela, vous ne pouvez pas attribuer un rang avant que le dernier élément de données ait été lu, et la maintenance de la liste est coûteuse. Par conséquent, les performances de la fonction Rank() dépendent du nombre total d'éléments à analyser et si le nombre est suffisant pour que le tri déborde sur le disque, les performances s'effondreront.
Ceci est probablement plus efficace:
select dept,
emp,
salary
from
(
SELECT dept,
emp,
salary,
Min(salary) Over (Partition By dept) min_salary
FROM mytable
)
where salary = min_salary
/
Cette méthode exige seulement que la requête à maintenir une valeur unique par département de la valeur minimum rencontrée jusqu'à présent. Si un nouveau minimum est rencontré, la valeur existante est modifiée, sinon la nouvelle valeur est ignorée. Le nombre total d'éléments qui doivent être conservés en mémoire est lié au nombre de départements et non au nombre de lignes analysées.
Il se peut qu'Oracle ait un chemin de code pour reconnaître que le rang n'a pas vraiment besoin d'être calculé dans ce cas, mais je ne parierais pas dessus. La deuxième raison de ne pas aimer Rank() est qu'il répond simplement à la mauvaise question. La question n'est pas "Quels enregistrements ont le salaire qui est le premier classement lorsque les salaires par département sont ordonnés à la hausse", c'est "Quels enregistrements ont le salaire qui est le minimum par département". Cela fait une grande différence pour moi, au moins.
Merci David. Après avoir considéré ses avantages, j'ai refactorisé à votre solution. –