3

Could someone help me understand something? When I can, I usually avoid (*) in an SQL statement. Well, today was payback. Here is a scenario:

CREATE TABLE Tbl (Id INT IDENTITY(1, 1) PRIMARY KEY, Name NVARCHAR(16))

INSERT INTO Tbl VALUES (N'John')
INSERT INTO Tbl VALUES (N'Brett')
INSERT INTO Tbl VALUES (NULL)

I could count the number of records where Name is NULL as follows:

SELECT COUNT(*) FROM Tbl WHERE Name IS NULL

While avoiding the (*), I discovered that the following two statements give me two different results:

SELECT COUNT(Id) FROM Tbl WHERE Name IS NULL
SELECT COUNT(Name) FROM Tbl WHERE Name IS NULL

The first statement correctly return 1 while the second statement yields 0. Why or How?

abatishchev
  • 98,240
  • 88
  • 296
  • 433
John Gathogo
  • 4,495
  • 3
  • 32
  • 48

6 Answers6

5

That's because

The COUNT(column_name) function returns the number of values (NULL values will not be counted) of the specified column

so when you count Id you get expected result, while counting Name no, but the answer provided by query is correct

Marco
  • 56,740
  • 14
  • 129
  • 152
  • Gosh! I'll be damned! Its indeed true. `SELECT COUNT(Name) FROM Tbl` only returns the number of columns not having `NULL`. Damnit! This means its just safer to use `(*)` in a `COUNT` function to evaluate records in a table - unless one knows that a field is not and will never be nullable – John Gathogo Nov 16 '11 at 07:50
  • usually you'll get a warning from SQL SERVER `Null value is eliminated by an aggregate or other SET operation.` since that issue often causes confusion. – Code Magician Nov 16 '11 at 08:03
1

Everything is described in COUNT (Transact-SQL).

COUNT ( { [ [ ALL | DISTINCT ] expression ] | * } )

ALL - is default

COUNT(*) returns the number of items in a group. This includes NULL values and duplicates.

COUNT(ALL expression) evaluates expression for each row in a group and returns the number of nonnull values.

Michał Powaga
  • 22,561
  • 8
  • 51
  • 62
1

"COUNT()" does not count NULL values. So basically:

SELECT COUNT(Id) FROM Tbl WHERE Name IS NULL

will return the number of lines where ("ID" IS NOT NULL) AND ("Name" IS NULL); result is "1"

While:

SELECT COUNT(Name) FROM Tbl WHERE Name IS NULL

will count the lines where ("Name" IS NOT NULL) AND ("Name" IS NULL); result will always be 0

Andy
  • 3,631
  • 2
  • 23
  • 32
0

As it was said, COUNT (column_name) doesn't count NULL values. If you don't want use COUNT(*) then use COUNT(1), but actualy you will not see difference in performance.

Igor Borisenko
  • 3,806
  • 3
  • 34
  • 49
0

"Always avoid using *" is one of those blanket statements that people blindly follow. If you knew the reasons why you were avoiding * then you would know that none of those reasons apply when doing count(*).

Brandon Moore
  • 8,590
  • 15
  • 65
  • 120
0

The * in COUNT(*) is not the same * in SELECT * FROM...

SELECT COUNT(*) FROM T; very specifically means the cardinality of the table expression T.

SELECT COUNT(1) FROM T; will generate the same results as COUNT(*) but if the contents of the parentheses is not * then it must be parsed.

SELECT COUNT(c) FROM T; where c is a nullable column in table T will count the non-null values.

P.S. I'm comfortable with using SELECT * FROM... in the right circumstances.

P.P.S. Your 'table' has no key: consider INSERT INTO Tbl VALUES ('John', 'John', 'John', NULL, NULL, NULL); would be allowed by the results would be nonsense.

onedaywhen
  • 55,269
  • 12
  • 100
  • 138