Dalam SQL, apa perbedaan antara jumlah (kolom) dan jumlah (*)?


205

Saya memiliki pertanyaan berikut:

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

Apa bedanya jika saya mengganti semua panggilan count(column_name)ke count(*)?

Pertanyaan ini terinspirasi oleh Bagaimana cara menemukan nilai duplikat dalam tabel di Oracle? .


Untuk mengklarifikasi jawaban yang diterima (dan mungkin pertanyaan saya), mengganti count(column_name)dengan count(*)akan mengembalikan baris tambahan pada hasil yang berisi a nulldan jumlah nullnilai dalam kolom.

Jawaban:


235

count(*)menghitung NULLs dan count(column)tidak

[sunting] menambahkan kode ini sehingga orang dapat menjalankannya

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

hasil 7 3 2


8
Hanya ingin tahu: jika Anda memiliki baris dengan semua NULL, apakah akan menghitung (*) masih menghitungnya, atau hanya menghitung (kolom) untuk semua kolom?
Joel Coehoorn

7
Apakah standar ini berlaku untuk DBMS?
Eclipse

51
Perlu disebutkan bahwa jika Anda memiliki kolom yang tidak dapat dibatalkan seperti ID, maka hitung (ID) akan secara signifikan meningkatkan kinerja melebihi hitungan (*).
tsilb

12
@tsilb: Jawaban yang diposting oleh @Alan menyatakan "count (*) dihitung dengan melihat indeks pada tabel yang dipermasalahkan daripada baris data aktual" yang, jika benar, membatalkan komentar Anda. Saya menghargai bahwa @lan mungkin salah tetapi saya tertarik pada sumber informasi Anda untuk mengetahui mana yang benar.
Tony

12
@tsilb: Banyak pengoptimal permintaan modern akan mengoptimalkan jumlah (*) untuk menggunakan indeks ketika masuk akal.
Shannon Severance

37

Perbedaan kecil lainnya, antara menggunakan * dan kolom tertentu, adalah bahwa dalam kasus kolom Anda dapat menambahkan kata kunci DISTINCT, dan membatasi hitungan ke nilai yang berbeda:

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

1
Haruskah grup menurut kolom dan yang dihitung berbeda? jika tidak, Anda tidak akan mendapatkan apa pun dari permintaan ini
steevc

Ya, maaf .. Saya tidak memperhatikan bahwa mereka adalah kolom yang sama dalam contoh. Saya akan memperbarui pos.
Brannon

16

Perbedaan lebih lanjut dan mungkin halus adalah bahwa dalam beberapa implementasi database hitungan (*) dihitung dengan melihat indeks pada tabel yang dipermasalahkan daripada baris data aktual. Karena tidak ada kolom khusus yang ditentukan, tidak perlu repot dengan baris aktual dan nilainya (seperti yang akan terjadi jika Anda menghitung kolom tertentu). Mengizinkan basis data untuk menggunakan data indeks dapat secara signifikan lebih cepat daripada membuatnya menghitung baris "nyata".


5
+1 Ya, tentu berlaku untuk Oracle, dan untuk PostgreSQL mulai dari 9.2 dan seterusnya.
David Aldridge

@ Davidvidld Bisakah Anda memberikan pointer ke dokumentasi (terutama untuk postgresql) di mana ini disebutkan? Terima kasih.
Bhushan


10

Penjelasan dalam dokumen , membantu menjelaskan hal ini:

COUNT (*) mengembalikan jumlah item dalam grup, termasuk nilai NULL dan duplikat.

COUNT (ekspresi) mengevaluasi ekspresi untuk setiap baris dalam grup dan mengembalikan jumlah nilai nonnull.

Jadi hitung (*) termasuk nol, metode lain tidak.


Untuk SQL newbs: Untuk file bantuan apa yang Anda maksud?
Bill the Lizard

10

Kita bisa menggunakan Stack Exchange Data Explorer untuk mengilustrasikan perbedaan dengan kueri sederhana. Tabel Pengguna di database Stack Overflow memiliki kolom yang sering dibiarkan kosong, seperti URL Situs Web pengguna.

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

Jika Anda menjalankan kueri di atas di Penjelajah Data , Anda akan melihat bahwa penghitungannya sama untuk count(Id)dan count(*)karena Idkolom tidak mengizinkan nullnilai. The WebsiteUrlcount jauh lebih rendah, meskipun, karena kolom yang memungkinkan null.


2

Pada dasarnya COUNT(*)fungsi mengembalikan semua baris dari tabel sedangkan COUNT(COLUMN_NAME)tidak; itu tidak termasuk nilai nol yang juga dijawab semua orang di sini. Tetapi bagian yang paling menarik adalah membuat kueri dan basis data dioptimalkan. Lebih baik digunakan COUNT(*)kecuali melakukan beberapa hitungan atau kueri yang kompleks COUNT(COLUMN_NAME). Jika tidak, itu benar-benar akan menurunkan kinerja DB Anda saat berhadapan dengan sejumlah besar data.


1
  • Kalimat COUNT (*) menunjukkan SQL Server untuk mengembalikan semua baris dari tabel, termasuk NULLs.
  • COUNT (nama_kolom) baru saja mengambil baris yang memiliki nilai bukan nol pada baris.

Silakan lihat kode berikut untuk pelaksanaan uji 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(*) - Mengembalikan jumlah total catatan dalam tabel (Termasuk catatan bernilai NULL).

COUNT(Column Name) - Mengembalikan jumlah total catatan Non-NULL. Ini berarti, mengabaikan mengabaikan catatan bernilai NULL di kolom tertentu.


0

Cara terbaik adalah menggunakan

Count(1) in place of column name or * 

untuk menghitung jumlah baris dalam sebuah tabel, itu lebih cepat daripada format apa pun karena tidak pernah memeriksa nama kolom ke dalam tabel ada atau tidak


4
Salah untuk Oracle setidaknya, dan untuk RDBMS lainnya juga saya curigai. Hitungan internal (1) ditransformasikan menjadi hitungan (*). Secara khusus, kinerja hitungan (*) tidak terpengaruh oleh ukuran baris, yang merupakan kesalahpahaman umum.
David Aldridge

Ini berlaku untuk SQL Server. Seperti @Ali Adravi katakan, COUNT(*)dibandingkan dengan COUNT(columnName)tidak akan pergi untuk memeriksa nilai kolom, karena hanya menghitung baris. Tetapi COUNT(columnName)lebih lambat bahkan countditerapkan pada idkolom! Setidaknya dalam SQL Server, tentu saja.
ABS

0

Tidak ada perbedaan jika satu kolom diperbaiki di tabel Anda, jika Anda ingin menggunakan lebih dari satu kolom daripada Anda harus menentukan berapa banyak kolom yang Anda butuhkan untuk dihitung ......

Terima kasih,


0

Seperti disebutkan dalam jawaban sebelumnya, Count(*)bahkan menghitung NULLkolom, sedangkan count(Columnname)dihitung hanya jika kolom memiliki nilai.

Itu selalu praktek terbaik untuk menghindari *( Select *, count *, ...)


Ini sama sekali bukan praktik terbaik untuk dihindariCOUNT(*)
David Faber
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.