T-SQL

COUNT() a eliminace NULL hodnot

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

NULL_values_ignored_in_COUNT

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

NULL_values_ignored_in_COUNT_2

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.

Leave a Reply

Your email address will not be published. Required fields are marked *