SQL Gym Pro 9 - Разбор задачи с WB Для начала, давайте вспомним, что такое медиана вообще. Медиана - это число, которое является серединой множества чисел, т.е зарплата человека, который стоит ровно посередине, если всех выстроить по росту доходов.
• Если людей нечетное количество (например, 5), то медиана - это зарплата 3-го человека. • Если четное (например, 4), то мы берем двух людей посередине (2-го и 3-го) и считаем среднее между их зарплатами.
Логика решения:
1️⃣ ЗП сотрудников записаны в рандомном порядке, т.е нам нужно отсортировать зарплаты по возрастанию и выдать каждому сотруднику его порядковый номер. За это отвечает оконная функция ROW_NUMBER() OVER (ORDER BY salary asc).
2️⃣ Там же давайте сразу посчитаем, сколько вообще всего людей в нашей выборке с помощью COUNT(*) OVER().
3️⃣ в SQL при делении целых чисел дробная часть просто отбрасывается. Смотрите, как это работает: • Если у нас 5 строк: (5 + 1) / 2 = 3. И (5 + 2) / 2 = 3 (потому что 7/2 в целых числах это 3). Условие вытащит ровно одну, 3-ю строку. • Если у нас 4 строки: (4 + 1) / 2 = 2 (потому что 5/2 = 2). А (4 + 2) / 2 = 3. Условие вытащит 2-ю и 3-ю строки.
4️⃣ В самом конце AVG(salary * 1.0) считает среднее. Умножение на 1.0 нужно, чтобы конвертировать целые числа (integer) в дробные и не потерять точность (например, если среднее между 50 и 65 будет 57.5, без 1.0 база округлит результат до 57).
Решение задачи: WITH cte AS ( SELECT employee_id, name, skill, salary, SUM(salary) OVER(ORDER BY skill DESC, salary) AS budget FROM employees ), ranked_salaries AS ( SELECT salary, ROW_NUMBER() OVER (ORDER BY salary ASC) AS rnk, COUNT(*) OVER() AS total_rows FROM cte WHERE budget <= 100 ) SELECT AVG(salary * 1.0) AS median FROM ranked_salaries WHERE rnk IN ( (total_rows + 1) / 2 , (total_rows + 2) / 2 );
Если хорошо подумать, то задачка достаточно простая) В ежедневной рабочей рутине мы все привыкли не глядя использовать встроенную функцию MEDIAN (или PERCENTILE_CONT).
Спасибо всем, кто отправлял решения, вы молодцы! #разборзадачи