Собесов

StrataScratch (Facebook) — доля активных пользователей из США

SQLДоли и пропорцииСредняяJunior

Условие

Таблица fb_active_users(user_id, name, status, country). status ∈ {open, closed}. Посчитайте долю пользователей, у которых одновременно status = 'open' И country = 'USA', к общему числу пользователей.

Округлить до 2 знаков, в виде доли (0.xx).

Решение

SELECT
  ROUND(
    SUM(CASE WHEN status = 'open' AND country = 'USA' THEN 1 ELSE 0 END)::DECIMAL
    / COUNT(*),
    2
  ) AS active_us_share
FROM fb_active_users;

Или через AVG

SELECT
  ROUND(AVG(CASE WHEN status = 'open' AND country = 'USA' THEN 1.0 ELSE 0 END), 2)
    AS active_us_share
FROM fb_active_users;

В Postgres/MySQL оба работают. В Oracle для AVG с булевыми CASE нужно 1 или 0 (как число), и 1.0 форсирует numeric.

Почему не «двойной» подзапрос

Соблазн: (SELECT COUNT(*) WHERE ... = 'open' AND country = 'USA') / (SELECT COUNT(*) FROM ...). Работает, но медленнее (два прохода) и int / int — обрезание. Условный SUM/AVG — один проход.

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

  1. int / int. SUM(CASE...) без ::DECIMAL даст 0 (если результат < 1). Классика SQL-боли.
  2. status мог быть NULL. Не попадёт ни в числитель, ни в знаменатель (если делать WHERE status IS NOT NULL). Решите по бизнес-смыслу: NULL — это «активные неизвестно?»; обычно нет.
  3. AND country = 'USA'. Если кейс — «или США, или активные» (OR), формула другая. Внимательно читаем условие.

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

ROUND(SUM(CASE WHEN status='open' AND country='USA' THEN 1 ELSE 0 END)::DECIMAL / COUNT(*), 2). Однопроходный запрос.

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

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

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