SQL: отбор заказов, группировка и ранжирование по исполнителю

Посчитать за март 2024 года заказы со статусом processing и приоритетом high по каждому исполнителю.

Короткий ответ

Что ответить на собеседовании

Посчитать за март 2024 года заказы со статусом processing и приоритетом high по каждому исполнителю. Вывести только исполнителей с заказами, по убыванию количества. Посчитать завершённые заказы по категориям для клиентов с ID ≥ 1002. Оставить категории со средней выручкой > 70000; неизвестную среднюю исключить. Добавить к результату по orderslog столбец rank: нумерацию записей каждого исполнителя по времени для статусов pending и processing.

Подробный разбор

Ответ с пояснениями

Условие

  1. Посчитать за март 2024 года заказы со статусом processing и приоритетом high по каждому исполнителю. Вывести только исполнителей с заказами, по убыванию количества.
  2. Посчитать завершённые заказы по категориям для клиентов с ID ≥ 1002. Оставить категории со средней выручкой > 70000; неизвестную среднюю исключить.
  3. Добавить к результату по orders_log столбец rank: нумерацию записей каждого исполнителя по времени для статусов pending и processing.

Ниже предполагаются поля status, priority, order_date, executor, category, client_id, revenue в orders и уникальный id, executor, timestamp, status в orders_log. Названия полей нужно согласовать с фактической схемой.

Решение

SELECT executor, COUNT(*) AS orders_count
FROM orders
WHERE status = 'processing'
  AND priority = 'high'
  AND order_date >= DATE '2024-03-01'
  AND order_date < DATE '2024-04-01'
GROUP BY executor
ORDER BY orders_count DESC;

Нулевых групп здесь не возникает: выбираем непосредственно заказы, без внешнего соединения со справочником исполнителей.

SELECT category, COUNT(*) AS completed_orders
FROM orders
WHERE status = 'completed' AND client_id >= 1002
GROUP BY category
HAVING AVG(revenue) > 70000;

AVG не учитывает NULL. Если все значения выручки в группе неизвестны, среднее равно NULL и условие HAVING не выполняется.

SELECT orders_log.*,
       ROW_NUMBER() OVER (
           PARTITION BY executor ORDER BY timestamp, id
       ) AS rank
FROM orders_log
WHERE status IN ('pending', 'processing');

В третьем решении rank — вычисляемый столбец результата, а не изменение схемы таблицы. Уникальный id устраняет неоднозначность при одинаковом времени. Если одинаковым временам нужен одинаковый ранг, следует уточнить условие и использовать RANK() или DENSE_RANK() с сортировкой только по времени. Если требуется именно хранить ранг, это отдельное требование: сохранённые значения придётся обновлять при изменении данных.

Оконные функции PostgreSQL.

Практика в реальном времени

Подготовьтесь к следующему собеседованию

Interview Boost учитывает вакансию, резюме и технологии и помогает сформулировать ответ прямо во время интервью.

Начать подготовку