Подсчет null и не null значений в SQL: одним запросом
Пройдите тест, узнайте какой профессии подходите
Быстрый ответ
Для подсчёта количества NULL и не NULL значений в столбце SQL вы можете использовать следующую технику:
SELECT
COUNT(имя_столбца) AS не_пустые, -- Считаем непустые значения
COUNT(*) – COUNT(имя_столбца) AS пустые -- Вычисляем количество пустых значений
FROM
имя_таблицы;
Функция COUNT(имя_столбца)
исключает NULL значения, в то время как COUNT(*)
учитывает их при подсчёте. Вычислив разницу между двумя показателями, мы получим количество значений NULL.
Примечания при работе с различными СУБД
Несмотря на универсальность представленного метода, важно знать о нюансах синтаксиса различных СУБД:
- В Oracle можно использовать оператор
MINUS
для вычисления разности между общим числом строк и количеством строк без NULL:
SELECT COUNT(*) FROM имя_таблицы
MINUS
SELECT COUNT(имя_столбца) FROM имя_таблицы;
- В SQL Server вместо
MINUS
используетсяEXCEPT
. Однако основной упомянутый ранее метод отлично работает на всех платформах, включая MySQL и PostgreSQL.
Комбинация SUM и CASE
Для большей гибкости можете применить сочетание функций SUM
и CASE
:
SELECT
SUM(CASE WHEN имя_столбца IS NULL THEN 1 ELSE 0 END) AS пустые, -- Подсчитываем NULL значения
SUM(CASE WHEN имя_столбца IS NOT NULL THEN 1 ELSE 0 END) AS не_пустые -- Подсчитываем не NULL значения
FROM
имя_таблицы;
Этот способ позволяет удобно учесть несколько условий, связанных с NULL значениями.
Визуализация
В качестве примера представим себе вместительный зал, где места могут быть заняты (✔️) или свободны (❓):
| Ряд | Статус |
|---------------|---------------|
| Передний ряд | ✔️✔️❓✔️ |
| Средний ряд | ❓❓✔️✔️ |
| Задний ряд | ✔️❓❓❓ |
Выявим занятые места с помощью запроса SQL:
SELECT
COUNT(place) AS 'Занятые_места', -- Счётчик для "Марко!"
COUNT(*) – COUNT(place) AS 'Свободные_места' -- Соответствует "Поло!"
FROM театр;
Итак, в результатах мы имеем два "прожектора":
- Один бросает свет на все занятые места (✔️):
COUNT(place)
- Второй освещает все свободные места (❓):
COUNT(*) – COUNT(place)
Совместив эти результаты, мы получаем полную картину занятости мест в зале!
Оптимизация производительности и масштабируемости
Эффективность запросов играет решающую роль, особенно при работе с большими объёмами данных:
- Полное сканирование таблицы — это как путешествие без конкретного назначения и может быть дорогостоящим по времени и ресурсам. Оптимизируйте процесс, используя план выполнения и проверьте использование индексов.
- Умело выбранные псевдонимы усиливают читабельность запросов, как и захватывающий поворот в сюжете удерживает внимание зрителя.
Учет особенностей вашей базы данных и оборудования позволит вам создать "кулинарный шедевр" на SQL.
Использование UNION ALL для дискриминации подсчётов
UNION ALL
поможет чётко разделить подсчёты по разным критериям:
SELECT 'Не пустые' AS Type, COUNT(имя_столбца) AS Count
FROM имя_таблицы
UNION ALL
SELECT 'Пустые', COUNT(*) – COUNT(имя_столбца)
FROM имя_таблицы;
Такой приём отлично подходит для формирования отчётов и экспорта данных.
Полезные материалы
- Count(*) vs Count(1) – SQL Server – Stack Overflow — особенности поведения функции
COUNT
с различными аргументами. - Modern SQL: IS DISTINCT FROM — оператор сравнения, не различающий NULL значения как разные — полезная статья о специфике работы со значениями NULL в SQL.
- MySQL :: Руководство по MySQL 8.0 :: 3.3.4.8 Подсчёт строк — официальная документация функции
COUNT()
от MySQL. - COUNT — детальное описание функции
COUNT
от Oracle. - PostgreSQL: Документация: 16: 9.18. Условные выражения — руководство по использованию условных выражений в SQL запросах из PostgreSQL.