Яка різниця між count (стовпець) та count (*) у 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(*)повертає додатковий рядок у результаті, який містить а nullта кількість nullзначень у стовпці.

Відповіді:


235

count(*)нараховує NULL і count(column)не робить

[редагувати] додав цей код, щоб люди могли його виконувати

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, чи порахували б (*) все ще його, або просто підрахунок (стовпець) для всіх стовпців?
Joel Coehoorn,

7
Це стандарт для СУБД?
Затемнення

51
Варто згадати, що якщо у вас стовпчик, який не зводиться на нуль, такий як ID, то count (ID) значно покращить ефективність щодо count (*).
цільб

12
@tsilb: Відповідь, опублікована @Alan заявляє, що "count (*) обчислюється, переглядаючи індекси відповідної таблиці, а не фактичні рядки даних", що, якщо це правда, скасовує ваш коментар. Я розумію, що @Alan може помилятися, але мене цікавить джерело вашої інформації, щоб дізнатися, що це правильно.
Тоні

12
@tsilb: Багато сучасних оптимізаторів запитів оптимізують кількість (*) для використання індексів, коли це має сенс.
Шеннон Северанс

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, щоб проілюструвати різницю простим запитом. Таблиця користувачів у базі даних Стек 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 (ім'я_колонки) просто витягує рядки, що мають на рядках ненулеве значення.

Будь ласка, дивіться наступний код для тестових виконання 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(*) - Повертає загальну кількість записів у таблиці (включаючи записи NULL).

COUNT(Column Name) - Повертає загальну кількість записів Non-NULL. Це означає, що він ігнорує підрахунок записів, що мають значення NULL, у цьому конкретному стовпці.


0

Найкраще використовувати

Count(1) in place of column name or * 

порахувати кількість рядків у таблиці, це швидше, ніж будь-який формат, тому що він ніколи не перевіряє ім'я стовпця в таблиці існує чи ні


4
Принаймні, для Oracle невірно, і для інших RDBMS я підозрюю. Внутрішнє число (1) перетворюється на рахунок (*). Зокрема, на показники підрахунку (*) не впливає негативно розмір рядків, що є поширеною помилковою думкою.
Девід Олдрідж

Це справедливо для SQL Server. Як сказав @Ali Adravi, COUNT(*)порівняно з COUNT(columnName)не буде переходити до перевірки значення стовпця, оскільки він просто перераховує рядки. Але COUNT(columnName)повільніше навіть countзастосований наid стовпчик! Принаймні, у SQL Server, звичайно.
ABS

0

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

Дякую,


0

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

Це завжди краще практика , щоб уникнути *( Select *, count *, ...)


Це зовсім не найкраща практика, якої слід уникатиCOUNT(*)
Девід Фабер
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.