Count(*), count(valami) és count(distinct valami)

Már háromszor is volt szó a count használatáról. Először általánosan, aztán az existtel kapcsolatban, majd a count_big és az int típusok használtánál.

Gondolom mindenki látja, hogy a fenti három kinézetre is különbözik, ezért sejteni lehet, hogy működésükben is más-más.

COUNT(*)

A count(*) megszámolja a visszakapott lekérdezésben szereplő sorokat. Akkor is, ha a tábla egy oszlopból áll és akkor is, ha sokból. Ha a sor tartalmaz NULL-t (az összes oszlopa NULL), akkor is beleszámít, mert az is egy sor. A DISTINCT sem játszik, tényleg minden sort számításba vesz, nem érdekli, ha vannak közte ugyanolyanok.

COUNT(valami)

A count(valami) nem a teljes sorok számát adja vissza, hanem a megadott oszlopban szereplő értékek számát. Ez azt jelenti, hogy ha az adott oszlopban NULL szerepel, akkor nem veszi figyelembe. Ez egyébként count(all valami) hivatalosan, de az ALL részét nem kötelező kiírni, ez az alapbeállítás.

A paraméter nem csak oszlopnév lehet, hanem mondjuk egy konstans is, ugyanúgy működik a count(1) is, ahol az 1 nem az oszlop számát jelenti, hanem egy sima érték. Lehetne akár count(‘hakapeszimaki’) is. Egyedül a NULL fog ki rajta, hiszen az olyan érték, ami az érték hiányát jelzi.

Ha a számlálás során NULL értékbe bukkan, ami miatt az adott értéket nem számolja, akkor egy figyelmeztetést is látunk: “Warning: Null value is eliminated by an aggregate or other SET operation”. Ilyenkor jó utánanézni a parancsunknak, hogy valóban ezt akartuk-e, hogy jó-e így számunkra az eredmény, és valószínűleg jó lesz a jövőben is. Esetleg elnyomhatjuk az ilyen típusú figyelmeztetéseket az ansi_warning kikapcsolásával, de ez nem ajánlott.

COUNT(DISTINCT valami)

A count(distinct valami) a count és a distinct alapján már érhető szerintem: az adott oszlopban levő egyedi értékeket számolja meg. A NULL itt sem játszik, azokat nem számolja és ugyanazt a figyelmeztetést adja, ha belefut ilyen esetbe. Paraméternek csak oszlopnevet érdemes megadni, mert egy count(distinct “konstans”) mindig 1-et fog visszaadni eredménynek, hiszen gyorsan megszámolja, hogy csak azt az egy értéket kell megszámolnia.

A count használja az indexeket, ha tudja. Vagyis ha van valamilyen index a táblán, akkor még a count(*) sem fog table scant végrehajtani, ha valamilyen indexet használhat.

Természetesen mindegyiknél lehet használni WHERE feltételt, OVER kikötést, HAVING szűrést, vagy egy jó kis GROUP BY csoportosítást, ahogy a legtöbb aggregate függvénnyel lehetséges.