Задачи на подзапросы и CTE
Подзапросы и CTE·middle·встречалась: банк

Типы операций в процессах без операций типа 2

Эту задачу давали на реальном собеседовании в банке. Она проверяет, умеешь ли ты разбить вопрос на два шага — сначала «найди подходящие процессы», потом «посчитай по ним» — и заметить дубли.

Задача

Ты аналитик в банке и работаешь с данными о внутренних процессах и операциях. Есть три таблицы:

  • t(id) — типы операций: 1, 2, 3.
  • p(pid) — процессы: 1..4.
  • o(oid, pid, id) — операции: какая операция в каком процессе и какого типа.

Данные: процесс 1 содержит операции типов 1, 2, 3; процесс 2 — типы 1, 3; процесс 3 — типы 2, 3; процесс 4 — три операции типа 1.

Выведи в разрезе типов операций количество процессов, в которых нет операций типа 2.

Схема данных

CREATE TABLE t (id int);
CREATE TABLE p (pid int);
CREATE TABLE o (oid int, pid int, id int);

Обрати внимание на процесс 4: у него три операции одного типа 1 — это ловушка на дубли при подсчёте.

Решение

SELECT o.id AS op_type, COUNT(DISTINCT o.pid) AS process_count
FROM o
WHERE o.pid IN (
  SELECT p.pid
  FROM p
  WHERE NOT EXISTS (
    SELECT 1 FROM o o2 WHERE o2.pid = p.pid AND o2.id = 2
  )
)
GROUP BY o.id
ORDER BY o.id;

Разбор

Задача распадается на два шага, и это её главный урок — не пытаться решить всё одним движением.

Шаг первый — найти процессы без операций типа 2. Это анти-джойн: «оставь процесс, для которого не существует операции типа 2». NOT EXISTS (SELECT 1 FROM o o2 WHERE o2.pid = p.pid AND o2.id = 2) возвращает процесс ровно тогда, когда внутри него нет ни одной строки с id = 2. Под условие подходят процессы 2 и 4. То же можно записать через NOT IN или LEFT JOIN ... IS NULL, но NOT EXISTS надёжнее — он не спотыкается о NULL.

Шаг второй — по операциям этих процессов сгруппировать по типу и посчитать процессы. И вот тут ловушка: у процесса 4 три операции типа 1, но процесс-то один. Если написать COUNT(*), он насчитает три и завысит ответ. Правильно — COUNT(DISTINCT o.pid): считаем уникальные процессы, а не строки операций.

Итог: тип 1 встречается в двух процессах (2 и 4), тип 3 — в одном (2). ORDER BY o.id делает вывод предсказуемым. Про то, когда выбрать подзапрос, CTE или временную таблицу для такой многошаговой логики, — в вопросе подзапрос, CTE или временная таблица.

Ожидаемый результат

op_type | process_count
--- | ---
1 | 2
3 | 1

Прорешай такие задачи сам

Читать разбор полезно, а настоящая прокачка — самому писать запросы и получать обратную связь. В симуляторе живая база и проверка запросов, лёгкий режим — бесплатно.

Прорешать в бесплатной песочнице

Смежные задачи

Вопросы по теме