sql - COUNT(*) vs. COUNT(1) vs. COUNT(pk): which is better? -
this question has answer here:
- count(*) vs count(1) 9 answers
i find these 3 variants:
select count(*) foo; select count(1) foo; select count(primarykey) foo;
as far can see, same thing, , find myself using 3 in codebase. however, don't same thing different ways. 1 should stick? 1 of them better 2 others?
bottom line
use either count(field)
or count(*)
, , stick consistently, , if database allows count(tablehere)
or count(tablehere.*)
, use that.
in short, don't use count(1)
anything. it's one-trick pony, want, , in rare cases equivalent count(*)
use count(*)
counting
use *
queries need count everything, joins, use *
select boss.boss_id, count(subordinate.*) boss left join subordinate on subordinate.boss_id = boss.boss_id group boss.id
but don't use count(*)
left joins, return 1 if subordinate table doesn't match parent table
select boss.boss_id, count(*) boss left join subordinate on subordinate.boss_id = boss.boss_id group boss.id
don't fooled advising when using *
in count, fetches entire row table, saying *
slow. *
on select count(*)
, select *
has no bearing each other, entirely different thing, share common token, i.e. *
.
an alternate syntax
in fact, if not permitted name field same table name, rdbms language designer give count(tablenamehere)
same semantics count(*)
. example:
for counting rows have this:
select count(emp) emp
and make simpler:
select count() emp
and left joins, have this:
select boss.boss_id, count(subordinate) boss left join subordinate on subordinate.boss_id = boss.boss_id group boss.id
but cannot (count(tablenamehere)
) since sql standard permits naming field same name table name:
create table fruit -- orm-friendly name ( fruit_id int not null, fruit varchar(50), /* same name table name, , let's say, forgot put not null */ shape varchar(50) not null, color varchar(50) not null )
counting null
and also, not practice make field nullable if name matches table name. have values 'banana', 'apple', null, 'pears' on fruit
field. not count rows, yield 3, not 4
select count(fruit) fruit
though rdbms sort of principle (for counting table's rows, accepts table name count's parameter), work in postgresql (if there no subordinate
field in of 2 tables below, i.e. long there no name conflict between field name , table name):
select boss.boss_id, count(subordinate) boss left join subordinate on subordinate.boss_id = boss.boss_id group boss.id
but cause confusion later if add subordinate
field in table, count field(which nullable), not table rows.
so on safe side, use:
select boss.boss_id, count(subordinate.*) boss left join subordinate on subordinate.boss_id = boss.boss_id group boss.id
count(1)
: one-trick pony
in particular count(1)
, one-trick pony, works on 1 table query:
select count(1) tbl
but when use joins, trick won't work on multi-table queries without semantics being confused, , in particular cannot write:
-- count subordinates belongs boss select boss.boss_id, count(subordinate.1) boss left join subordinate on subordinate.boss_id = boss.boss_id group boss.id
so what's meaning of count(1) here?
select boss.boss_id, count(1) boss left join subordinate on subordinate.boss_id = boss.boss_id group boss.id
is this...?
-- counting subordinates select boss.boss_id, count(subordinate.boss_id) boss left join subordinate on subordinate.boss_id = boss.boss_id group boss.id
or this...?
-- or count(1) count 1 boss regardless if boss has subordinate select boss.boss_id, count(*) boss left join subordinate on subordinate.boss_id = boss.boss_id group boss.id
by careful thought, can infer count(1)
same count(*)
, regardless of type of join. left joins result, cannot mold count(1)
work as: count(subordinate.boss_id)
, count(subordinate.*)
so use either of following:
-- count subordinates belongs boss select boss.boss_id, count(subordinate.boss_id) boss left join subordinate on subordinate.boss_id = boss.boss_id group boss.id
works on postgresql, it's clear want count cardinality of set
-- count subordinates belongs boss select boss.boss_id, count(subordinate.*) boss left join subordinate on subordinate.boss_id = boss.boss_id group boss.id
another way count cardinality of set, english-like (just don't make column name same table name) : http://www.sqlfiddle.com/#!1/98515/7
select boss.boss_name, count(subordinate) boss left join subordinate on subordinate.boss_code = boss.boss_code group boss.boss_name
you cannot this: http://www.sqlfiddle.com/#!1/98515/8
select boss.boss_name, count(subordinate.1) boss left join subordinate on subordinate.boss_code = boss.boss_code group boss.boss_name
you can this, produces wrong result: http://www.sqlfiddle.com/#!1/98515/9
select boss.boss_name, count(1) boss left join subordinate on subordinate.boss_code = boss.boss_code group boss.boss_name
Comments
Post a Comment