Вариант 1 — сортировка и смещение:
SELECT DISTINCT salary FROM employee ORDER BY salary DESC LIMIT 1 OFFSET 1;
Без DISTINCT при двух сотрудниках с максимальной зарплатой вернётся максимальная же. Если вторая зарплата отсутствует, результат пустой; чтобы вернуть NULL, оборачивают: SELECT (SELECT ... ) AS second_salary.
Вариант 2 — подзапрос:
SELECT max(salary) FROM employee WHERE salary < (SELECT max(salary) FROM employee);
Возвращает NULL, если второй нет; хорошо читается, но плохо обобщается на N.
Вариант 3 — оконная функция:
SELECT DISTINCT salary FROM (
SELECT salary, DENSE_RANK() OVER (ORDER BY salary DESC) AS r FROM employee
) t WHERE r = 2;
Обобщается на N-ю и на группы: PARTITION BY department_id — вторая зарплата в каждом отделе.
Ранжирующие функции: для зарплат 300, 300, 200: ROW_NUMBER — 1, 2, 3; RANK — 1, 1, 3; DENSE_RANK — 1, 1, 2. Для «второй по величине» нужен DENSE_RANK.