Віконністандарт SQL

NTH_VALUE

Бере значення з N-го рядка вікна: другого, третього…

Синтаксис

NTH_VALUE(<вираз>, <номер>) OVER (
  ORDER BY <критерій>
  ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING
)

NTH_VALUE(<вираз>, <номер>) OVER (
  PARTITION BY <група> ORDER BY <критерій>
  ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING
)

Як FIRST_VALUE, але для будь-якого номера: NTH_VALUE(salary, 2) — друга зарплата у вікні. Рядків не меншає, кожен отримує значення зі свого вікна. Якщо у вікні ще нема N-го рядка, результат — NULL.

Дані для прикладів

employees

namedepartmentsalarybonusphone
Emmabackend1200300+44 7700 900123
Liambackend1000NULLNULL
Oliviafrontend1350150+44 7700 900456
Noahfrontend950NULL+44 7700 900789
Sophiadesign1200200NULL

Ці таблиці вже створено в пісочниці — приклади нижче працюють із ними. Хочеш повторити у своїй базі — скопіюй SQL.

Друга зарплата поруч з кожною
SELECT name, salary,
NTH_VALUE(salary, 2) OVER (
ORDER BY salary DESC
ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING
) AS second_salary
FROM employees;
namesalarysecond_salary
Olivia13501200
Emma12001200
Sophia12001200
Liam10001200
Noah9501200
Без рамки — NULL на початку
SELECT name, salary,
NTH_VALUE(name, 2) OVER (ORDER BY salary DESC) AS second_so_far
FROM employees;
namesalarysecond_so_far
Olivia1350NULL
Emma1200Emma
Sophia1200Emma
Liam1000Emma
Noah950Emma

Без рамки вікно закінчується на поточному рядку (разом із рівними йому). У Olivia у вікні лише вона сама, тож другого рядка ще нема.

Друге ім'я в кожному відділіСкладніше
SELECT name, department, salary,
NTH_VALUE(name, 2) OVER (
PARTITION BY department ORDER BY salary DESC
ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING
) AS second_in_department
FROM employees;
namedepartmentsalarysecond_in_department
Emmabackend1200Liam
Liambackend1000Liam
Sophiadesign1200NULL
Oliviafrontend1350Noah
Noahfrontend950Noah

У design одна людина, тож другого нема — NULL.

Зверни увагу

Без рамки ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING перші рядки отримують NULL: вікно закінчується на поточному рядку, і N-го в ньому ще нема.

Друга за величиною зарплата — не завжди NTH_VALUE(salary, 2): якщо дві найбільші рівні, другий рядок дасть те саме число, що й перший. Друге різне значення знаходить DENSE_RANK.

Використати результат у WHERE того самого запиту не можна — спершу порахуй його в підзапиті, а фільтруй уже зовні.

Схожі функції