0Pricing
SQL Academy · Урок

CASE в ORDER BY и агрегатах

Условная сортировка и подсчёт

«CASE в ORDER BY и агрегатах» — бесплатный урок SQL Academy на CoddyKit. Это урок 4 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения SQL Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс SQL Academy содержит 4 уроков всего.

Сортировка с собственным приоритетом

Предложение ORDER BY в SQL обычно сортирует строки по естественному значению столбца. Но можно встроить выражение CASE в ORDER BY, чтобы создать полностью собственный порядок сортировки — такой, который невозможно получить с помощью одного столбца.

Этот приём особенно полезен, когда приоритет определяется бизнес-правилами, а не исходными значениями данных.

SELECT product_name, status
FROM products
ORDER BY
  CASE status
    WHEN 'urgent'   THEN 1
    WHEN 'active'   THEN 2
    WHEN 'pending'  THEN 3
    ELSE                 4
  END;

Как работает CASE внутри ORDER BY

Когда база данных вычисляет ORDER BY CASE ... END, она получает целое число (или любое другое сравнимое значение) для каждой строки. Затем строки сортируются по этому вычисленному значению, а не по исходному столбцу или дополнительно к нему.

Выражение CASE не сохраняется: оно существует только в течение выполнения запроса.

SELECT order_id, priority
FROM orders
ORDER BY
  CASE priority
    WHEN 'high'   THEN 1
    WHEN 'medium' THEN 2
    WHEN 'low'    THEN 3
    ELSE               9
  END,
  order_id;

Явная сортировка NULL

По умолчанию разные базы данных размещают NULL в начале или в конце отсортированного результата по-разному. CASE в ORDER BY позволяет точно определить положение NULL независимо от используемого движка базы данных.

SELECT employee_name, manager_id
FROM employees
ORDER BY
  CASE WHEN manager_id IS NULL THEN 0 ELSE 1 END,
  manager_id;

Условная сортировка по возрастанию и убыванию

CASE в ORDER BY также может имитировать условное направление сортировки. Сопоставив значения категорий с отрицательными числами, можно эффективно обратить порядок сортировки для определённых групп, сохранив обычный порядок для остальных.

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

SELECT task_name, due_date, is_overdue
FROM tasks
ORDER BY
  CASE WHEN is_overdue = 1 THEN 0 ELSE 1 END,
  due_date;

CASE внутри COUNT

Вы можете встроить выражение CASE в агрегатную функцию, например COUNT. Секрет в том, чтобы возвращать значение, отличное от NULL, для строк, которые нужно посчитать, и NULL для строк, которые нужно пропустить, поскольку COUNT игнорирует NULL.

SELECT
  COUNT(CASE WHEN status = 'active'   THEN 1 END) AS active_count,
  COUNT(CASE WHEN status = 'inactive' THEN 1 END) AS inactive_count
FROM users;

CASE внутри SUM — условные итоги

Размещение CASE внутри SUM позволяет складывать значения только при истинности условия, а для несовпадающих строк использовать ноль. Это очень распространённый приём для отчётов в виде сводных таблиц, в которых один столбец разбивается на несколько столбцов показателей.

SELECT
  SUM(CASE WHEN region = 'North' THEN sales_amount ELSE 0 END) AS north_total,
  SUM(CASE WHEN region = 'South' THEN sales_amount ELSE 0 END) AS south_total,
  SUM(CASE WHEN region = 'East'  THEN sales_amount ELSE 0 END) AS east_total
FROM sales;

Условное усреднение с помощью CASE

Тот же приём работает с AVG. Поскольку AVG игнорирует NULL, возврат NULL для строк, которые нужно исключить, позволяет вычислить среднее только по совпадающим строкам — без подзапроса.

SELECT
  AVG(CASE WHEN department = 'Engineering' THEN salary END) AS avg_eng_salary,
  AVG(CASE WHEN department = 'Marketing'   THEN salary END) AS avg_mkt_salary
FROM employees;

Группировка с CASE — разбиение строк на категории

Можно использовать CASE в списке GROUP BY или SELECT, чтобы разбить непрерывные значения на категории, а затем выполнить агрегацию по каждой категории. Так числовой столбец превращается в группы с метками без изменения исходных данных.

SELECT
  CASE
    WHEN age < 18             THEN 'Under 18'
    WHEN age BETWEEN 18 AND 35 THEN '18-35'
    WHEN age BETWEEN 36 AND 55 THEN '36-55'
    ELSE                            '56+'
  END AS age_group,
  COUNT(*) AS user_count
FROM users
GROUP BY
  CASE
    WHEN age < 18             THEN 'Under 18'
    WHEN age BETWEEN 18 AND 35 THEN '18-35'
    WHEN age BETWEEN 36 AND 55 THEN '36-55'
    ELSE                            '56+'
  END;

Использование псевдонима вместо повторения CASE

Повторять длинное выражение CASE и в SELECT, и в GROUP BY многословно. Некоторые базы данных (MySQL, PostgreSQL с обходными решениями) позволяют обращаться к псевдониму в ORDER BY, но не в GROUP BY. Самый безопасный переносимый подход — обернуть запрос в подзапрос или CTE и выполнить GROUP BY по псевдониму уже там.

WITH scored AS (
  SELECT
    customer_id,
    CASE
      WHEN total_spent >= 1000 THEN 'Gold'
      WHEN total_spent >= 500  THEN 'Silver'
      ELSE                          'Bronze'
    END AS tier
  FROM customers
)
SELECT tier, COUNT(*) AS customer_count
FROM scored
GROUP BY tier
ORDER BY
  CASE tier
    WHEN 'Gold'   THEN 1
    WHEN 'Silver' THEN 2
    ELSE               3
  END;

Сочетание ORDER BY CASE с ASC / DESC

После выражения CASE по-прежнему можно добавить ASC или DESC, а также указать дополнительные столбцы сортировки через запятые. Оценка CASE является лишь первым ключом сортировки; последующие столбцы обычным образом разрешают совпадения.

SELECT
  ticket_id,
  category,
  created_at
FROM support_tickets
ORDER BY
  CASE category
    WHEN 'billing'  THEN 1
    WHEN 'outage'   THEN 2
    WHEN 'feature'  THEN 3
    ELSE                 4
  END ASC,
  created_at ASC;

Практический пример — панель продаж

Вот реалистичный запрос, который объединяет агрегатную функцию на основе CASE с сортировкой на основе CASE. Он формирует сводку продаж по регионам и упорядочивает её так, чтобы регион с наибольшей выручкой всегда был первым, а «Прочие» перемещались в конец.

SELECT
  CASE
    WHEN region IN ('North', 'South', 'East', 'West') THEN region
    ELSE 'Other'
  END AS region_label,
  SUM(CASE WHEN status = 'completed' THEN amount ELSE 0 END) AS completed_sales,
  COUNT(CASE WHEN status = 'refunded' THEN 1 END)           AS refund_count
FROM orders
GROUP BY
  CASE
    WHEN region IN ('North', 'South', 'East', 'West') THEN region
    ELSE 'Other'
  END
ORDER BY completed_sales DESC;

Проверка знаний

Проверьте своё понимание использования CASE внутри ORDER BY и агрегатных функций.

Итоги урока

В этом уроке Вы научились объединять CASE с ORDER BY и агрегатными функциями:

  • CASE в ORDER BY — назначать строкам пользовательские баллы сортировки, управлять расположением NULL и сочетать несколько правил сортировки в одном запросе.
  • CASE в COUNT — возвращать значение, отличное от NULL, для включаемых строк и NULL (неявно или явно) для пропускаемых строк.
  • CASE в SUM / AVG — использовать 0 или NULL в качестве значения ELSE, чтобы за один проход формировать условные итоги и средние значения.
  • CASE в GROUP BY — объединять непрерывные или категориальные значения в именованные группы для агрегации.

Эти приёмы устраняют необходимость во многих подзапросах и позволяют легко создавать отчёты в стиле сводных таблиц с помощью обычного SQL.

Часто задаваемые вопросы

Урок «CASE в ORDER BY и агрегатах» бесплатный?

Да — полный текст урока «CASE в ORDER BY и агрегатах» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс SQL Academy, подпишись на CoddyKit PRO. Курс SQL Academy содержит 4 уроков всего.

Чему я научусь в уроке «CASE в ORDER BY и агрегатах»?

Условная сортировка и подсчёт Ты практикуешь SQL Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.

Нужен ли мне опыт, чтобы начать SQL Academy?

Предыдущий опыт не требуется. SQL Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 4 из 4.

Сколько времени занимает урок «CASE в ORDER BY и агрегатах»?

Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.

Можно ли писать и запускать код в этом уроке SQL Academy?

Да. Каждый урок SQL Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.

Все уроки этого курса

  1. Выражение CASE
  2. Поисковый и простой CASE
  3. Группировка и маркировка данных
  4. CASE в ORDER BY и агрегатах
← Назад к SQL Academy