Как подсчитать количество появлений категорий, созданных с помощью CASE без подзапроса в SQL? - PullRequest
0 голосов
/ 28 апреля 2020

Контекст

Вопрос

  • order таблица содержит id, ..., total_amt_usd, account_id

  • accounts таблица содержит id, name, ...

Рассмотрим приведенные выше таблицы, я хотел бы написать запрос SQL в :

  1. Категории клиентов на основе суммы, связанной с их покупками. К высшей категории относится любой, чей общий объем продаж всех заказов превышает 200 000 долларов США. Средняя категория составляет от 200 000 до 100 000 долларов США. Самая низкая категория - кто-нибудь до 100 000 долларов США. Предоставьте таблицу, которая включает уровень, связанный с каждой учетной записью. Таблица должна содержать имя учетной записи, общий объем продаж всех заказов для клиента и категорию, и должна быть заказана с первыми покупателями, перечисленными в списке.
  2. укажите количество счетов, связанных с каждым из категории, созданные в части 1.

Ответ

Часть 1

SELECT a.name, SUM(o.total_amt_usd) AS total_amt_spent,
       CASE WHEN SUM(o.total_amt_usd) >= 200000 THEN 'top'
            WHEN SUM(o.total_amt_usd) >= 100000 AND SUM(o.total_amt_usd) < 200000 THEN 'mid'
            ELSE 'low' END AS category
FROM orders o
JOIN accounts a
ON a.id=o.account_id
GROUP BY 1
ORDER BY 2 DESC;

Часть 2

SELECT category, COUNT(category)
FROM (SELECT a.name, SUM(o.total_amt_usd) AS total_amt_spent,
             CASE WHEN SUM(o.total_amt_usd) >= 200000 THEN 'top'
                  WHEN SUM(o.total_amt_usd) >= 100000 AND SUM(o.total_amt_usd) < 200000 THEN 'mid'
                  ELSE 'low' END AS category
       FROM orders o
       JOIN accounts a
       ON a.id=o.account_id
       GROUP BY 1
       ORDER BY 2 DESC) AS table1
GROUP BY category;

Запрос

Есть ли способ выполнить часть 2 без использования подзапроса? Я пытался включить COUNT() в тот же запрос, но продолжал получать ошибки.

1 Ответ

1 голос
/ 28 апреля 2020

Вам нужно два уровня агрегации. Но вам может не потребоваться join до accounts:

SELECT category, COUNT(*)
FROM (SELECT o.account_id, SUM(o.total_amt_usd) AS total_amt_spent,
             (CASE WHEN SUM(o.total_amt_usd) >= 200000 THEN 'top'
                   WHEN SUM(o.total_amt_usd) >= 100000 THEN 'mid'
                   ELSE 'low'
              END) AS category
       FROM orders o
       GROUP BY o.account_id
      ) a
GROUP BY category;

Это предполагает, что имя уникально в таблице accounts.

ORDER BY не подходит в подзапросе. Я также упростил логи c в выражении CASE, воспользовавшись тем, что условия оцениваются последовательно.

...