Как подсчитать строки по разным приоритетам в SQL

Пройдите тест, узнайте какой профессии подходите

Я предпочитаю
0%
Работать самостоятельно и не зависеть от других
Работать в команде и рассчитывать на помощь коллег
Организовывать и контролировать процесс работы

Быстрый ответ

В SQL для выполнения условного подсчёта используйте функцию COUNT в связке с конструкцией CASE:

SQL
Скопировать код
SELECT COUNT(CASE WHEN условие THEN 1 END) AS количество_условий FROM таблица;

Вместо условие подставьте заданное вами условие, а таблица замените на имя вашей таблицы. Данный подход позволяет подсчитать строки, соответствующие определённому условию, и вывести конечное количество_условий. Это эффективный метод подсчёта событий в данных.

Кинга Идем в IT: пошаговый план для смены профессии

Ключ к эффективным запросам: структурирование для повышения производительности

При работе с несколькими условиями или когда ваш запрос включает множество подсчетов, важно оптимизировать логику запроса для ускорения его выполнения. Использование SUM с CASE WHEN...END содействует достижению высокой производительности:

SQL
Скопировать код
-- Структура запроса для улучшения производительности
SELECT
  jobID, -- для наглядности отчета результаты группируются по jobID и JobName 
  JobName,
  SUM(CASE WHEN Priority = 'High' THEN 1 ELSE 0 END) AS количество_высокий_приоритет,
  SUM(CASE WHEN Priority = 'Medium' THEN 1 ELSE 0 END) AS количество_средний_приоритет,
  SUM(CASE WHEN Priority = 'Low' THEN 1 ELSE 0 END) AS количество_низкий_приоритет
FROM
  Jobs
GROUP BY
  jobID,
  JobName;

Допустим, у нас есть таблица Jobs со столбцами jobID, JobName и Priority. Группировка по jobID и JobName помогает отобразить количество задач в структурированном виде.

Альтернативный синтаксис в различных диалектах SQL

В SQL, как и в кулинарии, существуют множество альтернативных синтаксисов для разных баз данных. Рассмотрим IIF в SQL Server:

SQL
Скопировать код
SELECT jobID, JobName, 
COUNT(IIF(Priority = 'High', 1, NULL)) AS количество_высокий_приоритет
FROM Jobs 
GROUP BY jobID, JobName;

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

Читаемость – это закон, да здравствует запрос!

Правильное форматирование обеспечивает удобство чтения SQL-запроса, делая его структуру ясной и понятной. Разбивайте запрос на строки там, где это целесообразно, используйте отступы для отображения его структуры и не забывайте про комментарии:

SQL
Скопировать код
-- Запрос: универсальный инструмент работы с вашей базой данных
SELECT 
  JobName,
  SUM(CASE WHEN Priority = 'High' THEN 1 ELSE 0 END) AS количество_высокий,
  SUM(CASE WHEN Priority = 'Medium' THEN 1 ELSE 0 END) AS количество_средний,
  SUM(CASE WHEN Priority = 'Low' THEN 1 END) AS количество_низкий
FROM 
  Jobs
GROUP BY 
  JobName;

Учёт отсутствующих значений

Когда требуется учесть нулевые значения, LEFT JOIN в сочетании с COALESCE становятся наилучшими средствами. Эта комбинация позволяет извлекать значения приоритетов, заменяя отсутствующие подсчеты на нули:

SQL
Скопировать код
SELECT 
  j.JobName, 
  COALESCE(jp.HighCount, 0) AS количество_высокий,
  COALESCE(jp.MediumCount, 0) AS количество_средний,
  COALESCE(jp.LowCount, 0) AS количество_низкий
FROM 
  (SELECT DISTINCT Priority FROM Jobs) AS Priorities
LEFT JOIN  
  (SELECT 
    JobName, 
    SUM(CASE WHEN Priority = 'High' THEN 1 ELSE 0 END) AS HighCount,
    SUM(CASE WHEN Priority = 'Medium' THEN 1 ELSE 0 END) AS MediumCount,
    SUM(CASE WHEN Priority = 'Low' THEN 1 END) AS LowCount
   FROM 
     Jobs
   GROUP BY 
     JobName
  ) AS jp ON jp.Priority = Priorities.Priority;

Визуализация

Возьмём для примера план зала театра с обозначенными занятыми (🟢) и свободными (⚪️) местами, и нашей задачей будет подсчитать количество занятых мест в каждой секции.

Markdown
Скопировать код
| Секция | План зала             | Количество занято |
| ------- | --------------------- | ------------------ |
| A       | 🟢🟢⚪️🟢⚪️🟢            | **`COUNT`**: 4 |
| B       | 🟢⚪️⚪️⚪️🟢             | **`COUNT`**: 2 |
| C       | 🟢🟢🟢🟢🟢             | **`COUNT`**: 5 |

Данные — это сцена, а условный подсчёт — световой техник, который точно подсчитывает занятые места и предоставляет нам необходимую статистику по секциям.

Демонстрация работы со сложностью подзапросов

При работе с более сложными условиями и их комбинациями подзапросы становятся незаменимым инструментом:

SQL
Скопировать код
SELECT 
  j.JobName,
  jp.HighCount,
  jp.MediumCount,
  jp.LowCount
FROM 
  Jobs j
JOIN 
  (SELECT 
    jobID, 
    SUM(CASE WHEN Priority = 'High' THEN 1 ELSE 0 END) AS HighCount,
    SUM(CASE WHEN Priority = 'Medium' THEN 1 ELSE 0 END) AS MediumCount,
    SUM(CASE WHEN Priority = 'Low' THEN 1 ELSE 0 END) AS LowCount
   FROM 
     Jobs
   GROUP BY 
     jobID
  ) AS jp ON jp.jobID = j.jobID;

Объединение с помощью UNION ALL

Для соединения результатов из различных запросов используйте UNION ALL. Этот метод позволяет составить каталог всех приоритетов, даже если в некоторых категориях записи отсутствуют:

SQL
Скопировать код
SELECT 'High' as Priority, COUNT(*) as Количество FROM Jobs WHERE Priority = 'High'
UNION ALL
SELECT 'Medium', COUNT(*) FROM Jobs WHERE Priority = 'Medium'
UNION ALL
SELECT 'Low', COUNT(*) FROM Jobs WHERE Priority = 'Low';

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

Полезные материалы

  1. MySQL 8.0 Reference Manual – Aggregate Function Descriptions — официальное руководство MySQL по функции условного COUNT.
  2. PostgreSQL: Documentation: 9.18. Conditional Expressions — руководство по использованию конструкции CASE в PostgreSQL.
  3. Count(*) vs Count(1) – SQL Server — обсуждение на Stack Overflow об условных подсчетах в SQL Server.
  4. Questions — советы от экспертов Ask TOM по условной агрегации в Oracle SQL.
  5. SQL CASE | Intermediate SQL — универсальное руководство по CASE WHEN...END в SQL.