В чем разница между count (столбец) и count (*) в SQL?

У меня такой запрос:

select column_name, count(column_name)
from table
group by column_name
having count(column_name) > 1;

Какая была бы разница, если бы я заменил все вызовы с count(column_name) на count(*)?

Этот вопрос был вдохновлен Как найти повторяющиеся значения в таблице в Oracle?.


Чтобы прояснить принятый ответ (и, возможно, мой вопрос), замена count(column_name) на count(*) вернет дополнительную строку в результате, которая содержит null и количество значений null в столбце.

ReactJs | Supabase | Добавление данных в базу данных
ReactJs | Supabase | Добавление данных в базу данных
Это и есть ваш редактор таблиц в supabase.👇
Понимание Python и переход к SQL
Понимание Python и переход к SQL
Перед нами лабораторная работа по BloodOath:
207
0
45 323
11
Перейти к ответу Данный вопрос помечен как решенный

Ответы 11

Ответ принят как подходящий

count(*) считает NULL, а count(column) - нет.

[edit] добавил этот код, чтобы люди могли его запускать

create table #bla(id int,id2 int)
insert #bla values(null,null)
insert #bla values(1,null)
insert #bla values(null,1)
insert #bla values(1,null)
insert #bla values(null,1)
insert #bla values(1,null)
insert #bla values(null,null)

select count(*),count(id),count(id2)
from #bla

полученные результаты 7 3 2

Просто любопытно: если у вас есть строка с все NULL, будет ли count (*) по-прежнему считать ее или просто count (столбец) для всех столбцов?

Joel Coehoorn 12.09.2008 19:29

Это стандарт для СУБД?

Eclipse 23.01.2009 23:41

DB2 v9 выдает предупреждение: SQLSTATE 01003: значения NULL были исключены из аргумента функции столбца

Boune 17.06.2009 19:31

Стоит отметить, что если у вас есть столбец, не допускающий значения NULL, такой как ID, то count (ID) значительно повысит производительность по сравнению с count (*).

tsilb 25.08.2009 22:06

@tsilb: ответ, опубликованный @Alan, гласит, что «count (*) вычисляется путем просмотра индексов в рассматриваемой таблице, а не фактических строк данных», что, если оно истинно, делает ваш комментарий недействительным. Я понимаю, что @Alan может ошибаться, но меня интересует источник вашей информации, чтобы выяснить, какой из них правильный.

Tony 07.04.2010 00:55

@tsilb: многие современные оптимизаторы запросов оптимизируют count (*) для использования индексов, когда это имеет смысл.

Shannon Severance 20.08.2010 07:42

Что интересно, это приводит к тому, что count (DISTINCT имя столбца) подсчитывает только отличные от NULL значения, тогда как SELECT DISTINCT также возвращает нулевую строку, если есть одно или несколько значений NULL.

Zugwalt 24.03.2011 18:49

@SQLMenace Что делать, если я использую count (1)? Что это меня оставит?

renegadeMind 02.03.2012 01:53

@renegadeMind: если ваша цель - просто проверить, что таблица не пуста при поиске конкретных условий, вы можете сделать это if Exists (Select 1 from sys.tables where name = 'SalesChannel_PartyRole')

Michael Bahig 07.08.2012 14:58

Не должно быть улучшений в использовании count (column_name) по count (*), где column_name не равно нулю. любая выгода может быть получена от использования сканирования индекса вместо просмотра таблицы, но оптимизатор в любом случае может сделать это для count (*). В Oracle так было очень давно.

David Aldridge 04.04.2013 17:12

Неправильно говорить, что «count (*) подсчитывает нули» - наличие или отсутствие нулей не имеет значения, поскольку count (*) подсчитывает количество строк независимо от их содержимого.

David Aldridge 04.04.2013 17:13

@shannonSeverance, я считаю, что он действительно использует индекс в Mysql при использовании count (*) и count (1). Однако при использовании count (column_without_index) используется сканирование таблицы.

andy 10.08.2014 05:40

Объяснение в документы помогает объяснить это:

COUNT(*) returns the number of items in a group, including NULL values and duplicates.

COUNT(expression) evaluates expression for each row in a group and returns the number of nonnull values.

Итак, count (*) включает нули, а другой метод - нет.

Для новичков в SQL: к какому файлу справки вы имеете в виду?

Bill the Lizard 15.07.2009 19:33

Еще одно незначительное различие между использованием * и определенного столбца заключается в том, что в случае столбца вы можете добавить ключевое слово DISTINCT и ограничить счет отдельными значениями:

select column_a, count(distinct column_b)
from table
group by column_a
having count(distinct column_b) > 1;

Должны ли быть разные группы по столбцу и подсчитываемый? иначе вы бы ничего не получили из этого запроса

steevc 12.09.2008 20:06

Да, извините .. Я не заметил, что в примере это одна и та же колонка. Я обновлю пост.

Brannon 13.09.2008 02:31

Еще одно и, возможно, тонкое отличие состоит в том, что в некоторых реализациях базы данных счетчик (*) вычисляется путем просмотра индексов в рассматриваемой таблице, а не фактических строк данных. Поскольку конкретный столбец не указан, нет необходимости беспокоиться о фактических строках и их значениях (как это было бы, если бы вы подсчитали конкретный столбец). Разрешение базе данных использовать данные индекса может быть значительно быстрее, чем подсчет «реальных» строк.

+1 Да, конечно, верно и для Oracle, и для PostgreSQL начиная с 9.2.

David Aldridge 04.04.2013 17:18

@DavidAldridge Можете ли вы предоставить указатель на документацию (особенно для postgresql), где это упоминается? Спасибо.

Bhushan 17.04.2019 05:08

@Bhushan вот иди wiki.postgresql.org/wiki/Index-only_scans

David Aldridge 17.04.2019 11:00

Мы можем использовать Обозреватель данных Stack Exchange, чтобы проиллюстрировать разницу с помощью простого запроса. В таблице Users в базе данных Stack Overflow есть столбцы, которые часто остаются пустыми, например URL-адрес веб-сайта пользователя.

-- count(column_name) vs. count(*)
-- Illustrates the difference between counting a column
-- that can hold null values, a  'not null' column, and  count(*)

select count(WebsiteUrl), count(Id), count(*) from Users

Если вы запустите приведенный выше запрос в Проводник данных, вы увидите, что счетчик одинаков для count(Id) и count(*), потому что столбец Id не допускает значений null. Однако количество WebsiteUrl намного ниже, потому что в этом столбце разрешен null.

Лучше всего использовать

Count(1) in place of column name or * 

чтобы подсчитать количество строк в таблице, это быстрее, чем любой формат, потому что он никогда не проверяет имя столбца в таблице, существует или нет

Неправильно по крайней мере для Oracle, и я подозреваю, что для других СУБД тоже. Внутренне count (1) преобразуется в count (*). В частности, на производительность count (*) не влияет размер строк, что является распространенным заблуждением.

David Aldridge 04.04.2013 17:17

Это верно для SQL Server. Как сказал @Ali Adravi, COUNT(*) по сравнению с COUNT(columnName) не будет проверять значение столбца, потому что он просто перечисляет строки. Но COUNT(columnName) медленнее, даже count, примененный к колонке id! По крайней мере, в SQL Server, конечно.

ABS 25.07.2017 11:48
  • Предложение COUNT (*) указывает, что SQL Server должен вернуть все строки из таблицы, включая NULL.
  • COUNT (column_name) просто извлекает строки, имеющие ненулевое значение в строках.

См. Следующий код для выполнения тестов SQL Server 2008:

-- Variable table
DECLARE @Table TABLE
(
      CustomerId int NULL 
    , Name nvarchar(50) NULL
)

-- Insert some records for tests
INSERT INTO @Table VALUES( NULL, 'Pedro')
INSERT INTO @Table VALUES( 1, 'Juan')
INSERT INTO @Table VALUES( 2, 'Pablo')
INSERT INTO @Table VALUES( 3, 'Marcelo')
INSERT INTO @Table VALUES( NULL, 'Leonardo')
INSERT INTO @Table VALUES( 4, 'Ignacio')

-- Get all the collumns by indicating *
SELECT  COUNT(*) AS 'AllRowsCount'
FROM    @Table

-- Get only content columns ( exluce NULLs )
SELECT  COUNT(CustomerId) AS 'OnlyNotNullCounts'
FROM    @Table

Нет никакой разницы, если один столбец исправлен в вашей таблице, если вы хотите использовать более одного столбца, чем вы должны указать, сколько столбцов вам нужно подсчитать ...

Спасибо,

В основном функция COUNT(*) возвращает все строки из таблицы, тогда как COUNT(COLUMN_NAME) - нет; то есть исключает нулевые значения, на которые все здесь также ответили. Но самое интересное - это оптимизировать запросы и базу данных. Лучше использовать COUNT(*), если не выполняется несколько подсчетов или сложный запрос, а не COUNT(COLUMN_NAME). В противном случае это действительно снизит производительность вашей БД при работе с огромным количеством данных.

Как упоминалось в предыдущих ответах, Count(*) считает даже столбцы NULL, тогда как count(Columnname) считает, только если столбец имеет значения.

Всегда лучше избегать * (Select *, count *,…)

Избегать COUNT(*) - не лучшая практика.

David Faber 21.03.2018 03:32

COUNT(*) - возвращает общее количество записей в таблице (включая записи с нулевым значением).

COUNT(Column Name) - возвращает общее количество записей, отличных от NULL. Это означает, что он игнорирует подсчет записей со значением NULL в этом конкретном столбце.

Другие вопросы по теме