Oracle - функції rank () і dense_rank () (або вчимося вибирати необхідні значення всередині

Почнемо з функції RANK (). З пояснення для чого вона і в яких випадках вона нам може стати в нагоді.

Функція RANK () - це дуже корисна функція, вона дозволяє нам пронумерувати набір по деякому групуються значенням всередині всього обраного набору даних. Найпростіше показати це на прикладі. Для цього створимо невелику таблицю:


Нехай в цій таблиці буде містити деякі виставлені рахунки різним користувачам PERSON на різні суми SM в різний час DT.

А тепер припустимо що ми хочемо отримати по кожному користувачеві максимально виставлений йому рахунок за весь час.
Саме такого роду завдання дозволяє дуже легко вирішувати функція RANK ().

Для того, щоб домогтися бажаного результату, нам необхідно згрупувати користувачів з зарплатою за спаданням, ось так:
отримаємо:


Тепер, все що нам треба це тільки взяти по порядку перший запис для кожного користувача, в ній і буде максимальне значення. Ось для цього нам і знадобиться функція RANK ().
Для цього перепишемо наш запит ось так:
отримаємо:


Тепер ми отримали додатковий стовпець який нумерує значення за сумою (SM) всередині угруповань по кожній людині (PERSON).

Тепер все що нам залишається, це вибрати з отриманого набору ті записи в яких значення нового поля RNK = 1.

Отримуємо шуканий набір максимальних рахунків по кожному користувачеві:


Тепер спробуємо пояснити для чого ж нам функція DENSE_RANK (). По суті ці функції роблять одне і те ж, за дуже маленьким винятком, це виняток продемонструємо на прикладі. Для цього змінимо вихідний набір так, щоб в ньому було багато однакових значень суми рахунку (SM). Ось таким чином:


Тепер виконаємо вужа знайомий нам скрипт, додавши ще один стовпець який буде нумерувати нам угруповання, але тільки з функцією DENSE_RANK ():
Отримаємо результат:


Тепер ми можемо помітити різницю на персоні Романа, тут видно, що функція RANK () для наступної групи однакових значень поля SM привласнює порядковий номер запису всередині угруповання, тоді як функція DENSE_RANK () присвоює просто наступний порядковий номер. Ця різниця нам може стати в нагоді при вирішенні такого завдання, при якій необхідно вибрати не перший запис, а скажімо 3 або 4, і тут умова застосування тієї чи іншої функції може варіюватися в залежності від того, що ми хочемо отримати. Якщо ми хочемо отримати 3-е унікальне значення то правильніше буде використовувати DENSE_RANK (). за допомогою RANK () ми в даному випадку можемо отримати порядковий номер рядка шуканого значення.