W SQL jaka jest różnica między liczbą (kolumna) a liczbą (*)?


205

Mam następujące zapytanie:

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

Jaka byłaby różnica, gdybym zastąpił wszystkie połączenia count(column_name)zcount(*) ?

To pytanie zostało zainspirowane przez Jak znaleźć zduplikowane wartości w tabeli w Oracle? .


Aby wyjaśnić odpowiedź akceptowanej (i być może moje pytanie), zastępując count(column_name)z count(*)zwróciłby dodatkowy wiersz w wyniku, który zawiera nulli zliczania nullwartości w kolumnie.

Odpowiedzi:


235

count(*)liczy NULL i count(column)nie

[edit] dodał ten kod, aby ludzie mogli go uruchomić

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

wyniki 7 3 2


8
Po prostu ciekawa: jeśli masz wiersz ze wszystkimi wartościami NULL, to policzyłby (*) nadal go policzy, czy też jest tylko policzeniem (kolumna) dla wszystkich kolumn?
Joel Coehoorn

7
Czy ten standard dotyczy DBMS?
Zaćmienie

51
Warto wspomnieć, że jeśli masz kolumnę niepozwalającą wartości zerowej, taką jak ID, to liczba (ID) znacznie poprawi wydajność w stosunku do liczby (*).
tsilb

12
@tsilb: Odpowiedź wysłana przez @Alan mówi: „count (*) jest obliczany na podstawie indeksów w tabeli, o której mowa, a nie rzeczywistych wierszy danych”, co, jeśli jest prawdziwe, unieważnia twój komentarz. Rozumiem, że @Alan może się mylić, ale jestem zainteresowany źródłem twoich informacji, aby dowiedzieć się, co jest poprawne.
Tony

12
@tsilb: Wiele nowoczesnych optymalizatorów zapytań zoptymalizuje count (*), aby używać indeksów, gdy ma to sens.
Shannon Severance

37

Kolejną niewielką różnicą między użyciem * a określoną kolumną jest to, że w przypadku kolumny można dodać słowo kluczowe DISTINCT i ograniczyć liczbę do odrębnych wartości:

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

1
Czy grupa według kolumny i liczona ta powinny być różne? inaczej nie otrzymalibyście nic z tego zapytania
steevc 12.09.08

Tak, przepraszam .. Nie zauważyłem, że w tym przykładzie były to te same kolumny. Zaktualizuję posta.
Brannon

16

Dalszą i być może subtelną różnicą jest to, że w niektórych implementacjach bazy danych count (*) jest obliczany na podstawie indeksów w tabeli, a nie wierszy danych. Ponieważ nie określono konkretnej kolumny, nie trzeba zawracać sobie głowy faktycznymi wierszami i ich wartościami (tak jak by to było, gdyby policzyć konkretną kolumnę). Zezwolenie bazie danych na korzystanie z danych indeksu może być znacznie szybsze niż zliczanie „rzeczywistych” wierszy.


5
+1 Tak, z pewnością prawda dla Oracle i PostgreSQL od wersji 9.2.
David Aldridge

@DavidAldridge Czy możesz podać wskaźnik do dokumentacji (szczególnie dla postgresql), gdzie jest to wspomniane? Dzięki.
Bhushan


10

Wyjaśnienie w dokumentach pomaga to wyjaśnić:

COUNT (*) zwraca liczbę elementów w grupie, w tym wartości NULL i duplikaty.

COUNT (wyrażenie) ocenia wyrażenie dla każdego wiersza w grupie i zwraca liczbę wartości niepustych.

Więc count (*) zawiera null, druga metoda nie.


Dla SQL newbs: do którego pliku pomocy się odwołujesz?
Bill the Lizard

10

Możemy użyć Eksploratora danych wymiany stosu, aby zilustrować różnicę za pomocą prostego zapytania. Tabela Użytkownicy w bazie danych Przepełnienie stosu zawiera kolumny, które często są puste, takie jak adres URL witryny użytkownika.

-- 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

Jeśli uruchomisz powyższe zapytanie w Eksploratorze danych , zobaczysz, że liczba jest taka sama dla count(Id)i count(*)ponieważ Idkolumna nie dopuszcza nullwartości. WebsiteUrlLiczba jest znacznie mniejsza, chociaż, ponieważ kolumna pozwala null.


2

Zasadniczo COUNT(*)funkcja zwraca wszystkie wiersze z tabeli, podczas COUNT(COLUMN_NAME)gdy nie; to znaczy wyklucza wartości zerowe, na które wszyscy tutaj również odpowiedzieli. Ale najciekawsze jest zoptymalizowanie zapytań i bazy danych. Lepiej jest je stosować, COUNT(*)chyba że wykonujesz wiele zliczeń lub złożone zapytanie COUNT(COLUMN_NAME). W przeciwnym razie naprawdę obniży wydajność bazy danych, radząc sobie z ogromną liczbą danych.


1
  • Zdanie COUNT (*) oznacza, że ​​SQL Server zwraca wszystkie wiersze z tabeli, w tym NULL.
  • COUNT (nazwa_kolumny) po prostu pobiera wiersze o wartości innej niż null w wierszach.

Proszę zobaczyć następujący kod do wykonywania testów 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(*) - Zwraca całkowitą liczbę rekordów w tabeli (w tym rekordy o wartości NULL).

COUNT(Column Name) - Zwraca całkowitą liczbę rekordów innych niż NULL. Oznacza to, że ignoruje zliczanie rekordów o wartości NULL w tej konkretnej kolumnie.


0

Najlepiej użyć

Count(1) in place of column name or * 

aby policzyć liczbę wierszy w tabeli, jest szybszy niż jakikolwiek format, ponieważ nigdy nie idzie sprawdzić, czy nazwa kolumny w tabeli istnieje, czy nie


4
Podejrzewam, że przynajmniej niepoprawny dla Oracle, a także dla innych RDBMS. Licznik wewnętrzny (1) jest przekształcany na licznik (*). W szczególności na wydajność count (*) nie wpływa niekorzystnie rozmiar wierszy, co jest powszechnym błędnym przekonaniem.
David Aldridge,

Dotyczy to SQL Server. Jak powiedział @Ali Adravi, COUNT(*)w porównaniu z COUNT(columnName)nie przejdzie do sprawdzenia wartości kolumny, ponieważ po prostu wylicza wiersze. Ale COUNT(columnName)jest wolniejszy nawet countnałożony na idkolumnę! Oczywiście przynajmniej w SQL Server.
ABS

0

Nie ma różnicy, jeśli jedna kolumna jest poprawiona w tabeli, jeśli chcesz użyć więcej niż jednej kolumny, niż musisz określić, ile kolumn musisz policzyć ......

Dzięki,


0

Jak wspomniano w poprzednich odpowiedziach, Count(*)liczy się nawet NULLkolumny, natomiastcount(Columnname) liczy się tylko wtedy, gdy kolumna ma wartości.

To zawsze najlepszych praktyk, aby uniknąć *( Select *, count *...)


To wcale nie jest najlepsza praktyka, której należy unikaćCOUNT(*)
David Faber
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.