You know that doing COUNT
(*) on a table with a lot of columns and a lot of rows can take a lot of time and memory. There is a temptation to do COUNT
([Name]) where [Name] is the name of a column in the table. This can produce some surprising results. This is because of the way that COUNT
() works.
It counts the results of the query placed inside of it. SQL Server does a trick with the * in COUNT(*). It does count the rows. But COUNT([Name]) is funky. It counts only the results that are not NULL. This can throw your counts off if it is not what you are expecting. So I use COUNT(1) to be sure of what I’m getting in spite of NULL.
Run this script to see what I mean:
SET ANSI_NULLS ON; SET QUOTED_IDENTIFIER ON; IF EXISTS (SELECT object_id FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[CountTest]') AND type in (N'U') ) DROP TABLE [CountTest]; CREATE TABLE [CountTest]( [Name] [nvarchar](max) ); INSERT INTO [CountTest] ([Name]) VALUES('Sally'); INSERT INTO [CountTest] ([Name]) VALUES(NULL); INSERT INTO [CountTest] ([Name]) VALUES('Mary'); INSERT INTO [CountTest] ([Name]) VALUES('Jane'); INSERT INTO [CountTest] ([Name]) VALUES(NULL); INSERT INTO [CountTest] ([Name]) VALUES('Bob'); INSERT INTO [CountTest] ([Name]) VALUES('Tom'); INSERT INTO [CountTest] ([Name]) VALUES(NULL); -- Now we count SELECT COUNT(1) AS [COUNT(1) Should be 8] FROM [CountTest]; SELECT COUNT([Name]) AS [COUNT(Name) Won't be 8] FROM [CountTest]; SELECT COUNT(*) AS [COUNT(*) This is 8 too] FROM [CountTest]; SELECT [Name] FROM [CountTest]; -- should see 8 rows DROP TABLE [CountTest];