Myslím, že funkce Rank() není správná, a to ze dvou důvodů.
Za prvé je pravděpodobně méně efektivní než metoda založená na Min().
Důvodem je, že dotaz musí při skenování dat udržovat uspořádaný seznam všech platů na oddělení a hodnost bude poté přiřazena později opětovným přečtením tohoto seznamu. Je zřejmé, že při absenci indexů, které lze k tomu využít, nemůžete přiřadit hodnocení, dokud není přečtena poslední datová položka, a údržba seznamu je nákladná.
Výkon funkce Rank() tedy závisí na celkovém počtu prvků, které mají být prohledány, a pokud je počet dostatečný k tomu, aby se řazení rozlilo na disk, výkon se zhroutí.
Toto je pravděpodobně efektivnější:
select dept,
emp,
salary
from
(
SELECT dept,
emp,
salary,
Min(salary) Over (Partition By dept) min_salary
FROM mytable
)
where salary = min_salary
/
Tato metoda pouze vyžaduje, aby dotaz udržoval jedinou hodnotu pro každé oddělení s minimální hodnotou, se kterou se dosud setkal. Pokud je zjištěno nové minimum, stávající hodnota se upraví, jinak se nová hodnota zahodí. Celkový počet prvků, které musí být uloženy v paměti, souvisí s počtem oddělení, nikoli s počtem naskenovaných řádků.
Je možné, že Oracle má kódovou cestu, která rozpozná, že v tomto případě není ve skutečnosti nutné počítat hodnocení, ale na to bych nevsadil.
Druhým důvodem, proč se Rank() nelíbí, je ten, že odpovídá na špatnou otázku. Otázka nezní "V jakých záznamech je plat, který je na prvním místě, když jsou platy na oddělení seřazeny vzestupně", jde o to "Ve kterých záznamech je minimální mzda na oddělení". To je alespoň pro mě velký rozdíl.