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

205

У меня есть следующий запрос:

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(*)вернула бы дополнительную строку в результате, которая содержит a nullи количество nullзначений в столбце.

Билл Ящерица
источник

Ответы:

235

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

SQLMenace
источник
8
Просто любопытно: если у вас есть строка со всеми значениями NULL, будет ли count (*) все равно считаться или это просто count (столбец) для всех столбцов?
Джоэл Кохорн
7
Этот стандарт распространяется на СУБД?
Затмение
51
Стоит отметить, что если у вас есть необнуляемый столбец, такой как ID, то count (ID) значительно улучшит производительность по сравнению с count (*).
Цилб
12
@tsilb: ответ, опубликованный @Alan, гласит, что «count (*) вычисляется путем просмотра индексов в рассматриваемой таблице, а не фактических строк данных», что, если оно истинно, делает ваш комментарий недействительным. Я ценю, что @Alan может ошибаться, но мне интересен источник вашей информации, чтобы выяснить, какая из них правильная.
Тони
12
@tsilb: Многие современные оптимизаторы запросов оптимизируют count (*) для использования индексов, когда это имеет смысл.
Шеннон Северанс
37

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

select column_a, count(distinct column_b)
from table
group by column_a
having count(distinct column_b) > 1;
Brannon
источник
1
Должны ли группы по столбцам и подсчитываемые отличаться? в противном случае вы ничего не получите от этого запроса
steevc
Да, извините .. Я не заметил, что это были те же столбцы в примере. Я обновлю пост.
Браннон
16

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

Алан
источник
5
+1 Да, конечно, верно для Oracle и PostgreSQL с 9.2 и выше.
Дэвид Олдридж
@DavidAldridge Можете ли вы предоставить указатель на документацию (особенно для postgresql), где это упоминается? Спасибо.
Бхушан
@Bhushan вот ты иди wiki.postgresql.org/wiki/Index-only_scans
Дэвид Олдридж
10

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

COUNT (*) возвращает количество элементов в группе, включая значения NULL и дубликаты.

COUNT (выражение) вычисляет выражение для каждой строки в группе и возвращает количество ненулевых значений.

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

Питер С
источник
Для новичков SQL: на какой справочный файл вы ссылаетесь?
Билл Ящерица
10

Мы можем использовать Stack Exchange Data Explorer, чтобы проиллюстрировать разницу простым запросом. Таблица 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.

Билл Ящерица
источник
2

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

Ахмедул Кабир
источник
1
  • Предложение 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
G21
источник
1

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

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

Арун Соломон
источник
0

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

Count(1) in place of column name or * 

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

Али Адрави
источник
4
По крайней мере, неверно для Oracle и для других СУБД. Внутренний счет (1) преобразуется в счет (*). В частности, на производительность count (*) не влияет размер строк, что является распространенным заблуждением.
Дэвид Олдридж
Это верно для SQL Server. Как сказал @Ali Adravi, COUNT(*)по сравнению с ним COUNT(columnName)не пойдет проверять значение столбца, поскольку он просто перечисляет строки. Но COUNT(columnName)медленнее даже countнанесенного на idстолб! По крайней мере, в SQL Server, конечно.
АБС
0

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

Спасибо,

Хирен гардхария
источник
0

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

Это всегда лучше практика , чтобы избежать *( Select *, count *, ...)

Унна
источник
Это вовсе не лучшая практика, которую следует избегатьCOUNT(*)
Дэвид Фабер,