Agregační funkce v SQL serveru ignorují hodnoty NULL. V praxi to znamená, že pokud agregujeme data ve sloupcích a některé řádky obsahují NULL hodnoty, tyto hodnoty se do naší agregace nezapočítají. Pro funkce typu SUM() je to očekávané chování, ale již ne tak pro AVG() nebo COUNT(). Funkce COUNT() se chová ještě více specificky, protože můžeme kromě sloupce (jako u jiných funkcí) využít i asterix – COUNT(*). K čemu tento rozdíl vede si ukážeme dále v článku.
Vytvoříme si testovací tabulku s jedním sloupcem ID, do kterého vyplníme pět hodnot, z nichž jedna je NULL:
CREATE TABLE [dbo].[SampleTable]( [ID] [int] NULL ) ON [PRIMARY] GO INSERT INTO [dbo].[SampleTable] ([ID]) SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT NULL UNION ALL SELECT 5 GO
Nyní spustíme tyto dva dotazy a porovnáme jejich výstup:
SELECT COUNT(*) FROM dbo.SampleTable SELECT COUNT(ID) FROM dbo.SampleTable GO
První dotaz s COUNT(*) nám vrátil pět řádků, protože COUNT() s aterixem (*) nám vrací počet řádků přes všechny sloupce = celou tabulku. COUNT(ID) provádí agregaci nad konkrétním sloupcem a zde se chová jako jiné agregační funkce a hodnoty NULL ignoruje. Proto je v prvím případě výsledek 5 (celkový počet řádků v tabulce) a ve druhém 4 (počet NOT NULL hodnot ve sloupci ID).
Že se nejedná o příliš intuitivní chování, ale hlavně se nejedná o přesnou implementaci ANSI standardu SQL, nás SQL Server upozorní v okně zpráv, kde se po vykonání druhého dotazu zobrazí následující varování:
Varování můžeme potlačit nastavením SET ANSI_WARNINGS { ON | OFF }, které je ve výchozím nastavením ON, případně lze varování potlačit pro celý server a všechna připojení pomocí sp_configure. Změnu tohoto nastavení však nezle doporučit a pro řadu operací je vyžadováno nastavení SET_ANSI_WARNINGS na výchozí hodnotu ON.