Собесов

Лиги Цифровой экономики: типы клиентов с приоритетом «a»

SQLУсловные агрегацииЛёгкаяJunior

Условие

В таблице table хранятся связки клиентов и их типов: поле type принимает только 'a' или 'b'. Если клиент связан с обоими типами, считаем его типом 'a'.

Подсчитайте число уникальных клиентов в каждом типе.

client | type
1      | a
1      | b
1      | b
2      | b
3      | a

Ожидаемо: тип 'a' = 2 (клиент 1 «приоритетно a», клиент 3), тип 'b' = 1 (клиент 2).

Решение

Подход

  1. Для каждого клиента определить итоговый тип: если есть 'a' — это 'a', иначе 'b'.
  2. Сгруппировать по этому итоговому типу.

SQL

WITH client_type AS (
  SELECT
    client,
    CASE WHEN MAX(CASE WHEN type='a' THEN 1 ELSE 0 END) = 1 THEN 'a' ELSE 'b' END AS final_type
  FROM table
  GROUP BY client
)
SELECT final_type, COUNT(*) AS cnt
FROM client_type
GROUP BY final_type;

Альтернатива через STRING_AGG или BOOL_OR

WITH ct AS (
  SELECT
    client,
    CASE WHEN BOOL_OR(type='a') THEN 'a' ELSE 'b' END AS final_type
  FROM table
  GROUP BY client
)
SELECT final_type, COUNT(*) FROM ct GROUP BY final_type;

Минимальная версия (без CTE)

SELECT
  CASE WHEN BOOL_OR(type='a') THEN 'a' ELSE 'b' END AS final_type,
  COUNT(DISTINCT client) AS cnt
FROM table
GROUP BY client
-- ... но тогда GROUP BY клиент, а COUNT — вне; см. CTE-версию выше как стандарт.

Результат на примере

final_type cnt
a 2
b 1

Подводные камни

  1. Если type может принимать NULLBOOL_OR(type='a') корректно вернёт FALSE, но клиент с одним NULL уйдёт в категорию 'b'. Уточнить.
  2. Если type может содержать 'A' (с регистром) — добавить LOWER(type)='a'.
  3. Не забывать GROUP BY client в первой стадии — иначе MAX/BOOL_OR агрегируют всю таблицу.
  4. Версия с EXISTS: WHERE EXISTS (SELECT 1 FROM table t2 WHERE t2.client=t.client AND t2.type='a') — тоже работает, но менее эффективно.

Эталонный ответ

На каждом клиенте BOOL_OR(type='a')final_type; затем GROUP BY final_type, COUNT(*). Клиент с обоими типами уходит в 'a'.

Хочешь увидеть разбор?

Зарегистрируйся бесплатно — откроется развёрнутое решение этой задачи и ещё 4 на выбор.

Зарегистрироваться и увидеть разбор
Уже есть аккаунт? Войти