COUNT в SQL, объяснение для начинающих
COUNT выглядит как самая простая функция в SQL, и именно она незаметно сбивает с толку большинство людей на собеседованиях и на работе. Путаница почти всегда одна и та же: COUNT(*), COUNT(column), и COUNT(DISTINCT column) выглядят почти одинаково, но считают три разные вещи. Как только вы сможете сказать вслух, что каждый из них имеет значение, многое откроется. Вы можете проверить миграцию данных, найти дубликаты и измерить степень полноты столбца — и все это с помощью одной и той же маленькой функции. Это руководство и представляет собой объяснение с множеством небольших примеров, которые вы можете скопировать.
COUNT(*) имеет значение Строки. COUNT(column) имеет значение строки, в которых этот столбец не равен NULL. COUNT(DISTINCT column) имеет значение сколько разных значений, отличных от NULL в этом столбце есть. Все, что ниже, — это всего лишь предложение, замедленное.- Три формы COUNT и что каждая из них учитывает
- Правило NULL, которое заставляет их не соглашаться
- COUNT(*) против COUNT(DISTINCT): разница, о которой спрашивают интервьюеры
- COUNT с GROUP BY: подсчет по группе
- Как аналитики используют COUNT при миграции данных
- Использование COUNT в вашем собственном проекте портфолио
- Шпаргалка COUNT
Три формы COUNT и что каждая из них учитывает
Представьте себе один маленький столик, customers, с region столбец, в котором две строки никогда не заполнялись:
| id | имя | Регион |
|---|---|---|
| 1 | Майя | Север |
| 2 | Иордания | Юг |
| 3 | Алекс | Север |
| 4 | Сэм | NULL |
| 5 | Тейлор | NULL |
Теперь запустите на нем три формы:
SELECT
COUNT(*) AS all_rows,
COUNT(region) AS rows_with_region,
COUNT(DISTINCT region) AS different_regions
FROM customers;
| все_строки | rows_with_region | разные_регионы |
|---|---|---|
| 5 | 3 | 2 |
COUNT(*)= 5. В каждой строке, без исключений.*означает «саму строку», поэтому значения NULL не имеют значения.COUNT(region)= 3. Только те строки, гдеregionимеет ценность. Сэм и Тейлор пропущены, поскольку их регион равен NULL.COUNT(DISTINCT region)= 2. Просто разные значенияNorthиSouth. Два севера сворачиваются в один, а NULL не учитывается.
Правило NULL, которое заставляет их не соглашаться
Сначала спрогнозируйте это. В таблице 100 строк. У двадцати из них нет адреса электронной почты. Что вам дает подсчет столбца электронной почты? Назовите число, прежде чем читать дальше.
Вот весь трюк в одной строке:
COUNT(*) считает строки. COUNT(something) подсчитывает значения, отличные от NULL, этого чего-то.
Таким образом, в тот момент, когда в столбце есть NULL, COUNT(column) возвращается меньше чем COUNT(*). Этот пробел не является ошибкой, это информация: именно в скольких строках отсутствует значение в этом столбце.
SELECT COUNT(*) - COUNT(region) AS missing_regions
FROM customers; -- returns 2Еще одно последствие, о котором люди забывают: потому что COUNT(column) игнорирует NULL, COUNT(1) и COUNT(*) это одно и то же (константа 1 никогда не является NULL), но COUNT(a_column_full_of_nulls) может быть 0. Если вам просто нужно узнать, сколько строк, нажмите COUNT(*) и никогда больше не думать об этом.
COUNT(*) против COUNT(DISTINCT): разница, о которой спрашивают интервьюеры
Это классический вопрос о воспоминании, и на него стоит ответить без колебаний. Произнесите свой ответ вслух сейчас, одним предложением, прежде чем смотреть на таблицу. Читать таблицу и кивать — это не то же самое, что уметь произнести это в комнате.
| Ты пишешь | Ты вернешься |
|---|---|
COUNT(*) | Сколько там рядов. |
COUNT(order_id) | Сколько строк имеют идентификатор заказа (отличный от NULL). |
COUNT(DISTINCT order_id) | Сколько другой order_ids есть. |
Когда эти цифры различаются, вы чему-то научились. Если COUNT(*) больше, чем COUNT(DISTINCT order_id), некоторый идентификатор заказа появляется более одного раза, что означает, что у вас есть повторяющиеся строки. Это единственное сравнение — самая быстрая проверка дубликатов в SQL:
SELECT
COUNT(*) AS total_rows,
COUNT(DISTINCT order_id) AS unique_orders,
COUNT(*) - COUNT(DISTINCT order_id) AS duplicate_rows
FROM orders;
если duplicate_rows является 0, каждый заказ указывается один раз. Если оно больше нуля, именно столько дополнительных копий скрывается в таблице.
COUNT с GROUP BY: подсчет по группе
Само по себе, COUNT дает одно число для всей таблицы. Добавлять GROUP BY и это дает одно число За группу вместо. GROUP BY сортирует строки по ячейкам по столбцу, который вы называете, и COUNT работает внутри каждого контейнера:
SELECT region, COUNT(*) AS customers
FROM customers
GROUP BY region
ORDER BY customers DESC;
| Регион | Клиенты |
|---|---|
| Север | 2 |
| Юг | 1 |
| NULL | 2 |
GROUP BY сохраняет NULL в качестве своего собственного контейнера, поэтому два клиента с пустой областью отображаются как группа NULL из 2. Это отличается от COUNT(region), что полностью отбрасывает их. Те же данные, два честных ответа, потому что вы задали два разных вопроса.Тонкое, но важное сочетание: COUNT(*) считает каждую строку в группе, в то время как COUNT(column) учитываются только те строки в группе, где заполнен этот столбец. Группировка клиентов по регионам и чтение COUNT(*) рядом с COUNT(email) сообщает вам в каждом регионе, сколько у вас клиентов и скольким из них вы действительно можете отправить электронное письмо.
Как аналитики используют COUNT при миграции данных
Данные часто перемещаются из одного места в другое: CSV в базу данных, старая система в новую, необработанная таблица в очищенную. COUNT это первое, что вы запускаете с обеих сторон. Это самый дешевый способ ответить на вопрос: «Все ли пришло и что-нибудь прокралось дважды?» Большую часть суммы покрывают три проверки.
1. Все ли строки пришли? (сверка количества строк)
Посчитайте источник, посчитайте пункт назначения и сравните. Они должны точно совпадать.
SELECT COUNT(*) FROM customers_raw; -- the imported original
SELECT COUNT(*) FROM customers; -- the cleaned copy
Если в очищенной таблице меньше строк, значит, на этапе очистки были удалены записи (возможно, фильтр был слишком агрессивным). Если их больше, соединение разветвляется и умножает строки. В любом случае, два несовпадающих значения — это ваш сигнал остановиться и посмотреть, прежде чем строить что-то сверху.
2. Создала ли миграция дубликаты? (COUNT против COUNT DISTINCT)
Выберите столбец, который должен быть уникальным (ключ, например customer_id) и сравните два значения:
SELECT
COUNT(*) AS rows,
COUNT(DISTINCT customer_id) AS unique_ids
FROM customers;
если rows больше, чем unique_ids, один и тот же клиент попадает в таблицу более одного раза, и каждая сумма, которую вы вычислите позже, будет завышена. Это одно сравнение выявляет целый класс ошибок миграции.
3. Насколько заполнен каждый столбец? (COUNT(*) против COUNT(столбец))
Для любого столбца, который вас интересует, скорость заполнения — это всего лишь два значения, расположенных рядом:
SELECT
COUNT(*) AS rows,
COUNT(email) AS has_email,
ROUND(100.0 * COUNT(email) / COUNT(*), 1) AS email_pct
FROM customers;
Теперь вместо того, чтобы гадать, вы можете сказать: «У 94% перенесенных клиентов есть адрес электронной почты». Сделайте это для важных столбцов, и вы получите отчет о полноте, прежде чем кто-либо его попросит.
Использование COUNT в вашем собственном проекте портфолио
Представьте себе уже имеющийся у вас набор данных и три числа, которые это вам даст: сколько строк, сколько различных значений в вашем основном столбце и сколько строк не содержат этого значения. Если эти три цифры вас удивят, значит, вы еще не знаете своих данных. Каждый набор данных заслуживает одного и того же первого шага. Прежде чем написать одно сообщение, запустите COUNT, чтобы понять, что вы имеете в виду. Например, в наборе данных игр:
-- How big is it, and how many distinct studios and genres?
SELECT
COUNT(*) AS games,
COUNT(DISTINCT developer) AS studios,
COUNT(DISTINCT genre) AS genres
FROM games;
-- Which columns are patchy? (compare each to the row count)
SELECT
COUNT(*) AS rows,
COUNT(price) AS has_price,
COUNT(release_date) AS has_date
FROM games;
Руководить описанием проекта со словами «в наборе данных 83 201 игра в 41 жанре, а у 6% не указана дата выпуска» — это похоже на аналитика, а не на новичка. Это также защищает вас: знание того, где находятся NULL, не позволяет вам впоследствии незаметно недосчитаться. Привычка «сначала посчитать, потом проанализировать» — именно то, что Исследовательский анализ данных гид опирается на что Документирование ограничений данных руководство превращается в письменную запись.
Шпаргалка COUNT
| Вы хотите знать… | Писать |
|---|---|
| Сколько строк в этой таблице | COUNT(*) |
| Сколько строк имеют значение в этом столбце | COUNT(column) |
| В скольких строках отсутствует это значение? | COUNT(*) - COUNT(column) |
| Сколько разных значений имеет столбец | COUNT(DISTINCT column) |
| Есть ли в ключевом столбце дубликаты | COUNT(*) против COUNT(DISTINCT key) |
| Количество для каждой категории | COUNT(*) … GROUP BY category |
| Какая часть столбца заполнена | COUNT(column) * 100.0 / COUNT(*) |
SQL для аналитиков составляет 458 страниц, если считать по отдельности, включая то, что каждая версия делает с NULL.
SQL для аналитиков, 19 $ →тот Курс SQL обучает основам аналитического SQL на рабочих примерах, интерактивной лаборатории JOIN и Агрегация, которую вы запускаете в браузере, флэш-карточках и пробном экзамене. Нечего устанавливать.
Откройте набор SQL →Или приступайте к делу и учитесь, написав запросы: открыть SQL-практикум, тринадцать запросов, каждый из которых добавляет что-то одно к последнему.