В 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


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;

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

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

16

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


5
+1 Да, конечно, верно для Oracle и PostgreSQL с 9.2 и выше.
Дэвид Олдридж

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


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

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(*)
Дэвид Фабер,
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.