Kolik řádků splňuje podmínku
Školení, která pořádám
Pokud chceme zjistit, kolik řádků splňuje nějakou podmínku, můžeme použít jednoduché SELECT COUNT(*) FROM tab WHERE sloupec = hodnota
, při požadavku na seskupení potom SELECT skupina, COUNT(*) FROM tab WHERE sloupec = hodnota GROUP BY skupina
.
Co však v případě, že nás zajímá i celkový počet řádků nebo třeba poměr řádků, které podmínku splňují? Samozřejmě bychom mohli položit dva dotazy a následně jejich výsledek v kódu spojit, existuje ale elegantnější řešení: SELECT COUNT(*), SUM(IF(sloupec = hodnota, 1, 0)) FROM tab
. Výraz SUM(IF(sloupec = hodnota, 1, 0))
přičte jedničku pro každý řádek, který podmínku splňuje. Vzhledem k tomu, že v MySQL je výsledek logických operací vždy 1 nebo 0, dalo by se použít i jednodušší SUM(sloupec = hodnota)
, vzhledem k nižší čitelnosti bych to ale spíše nedoporučoval.
Přijďte si o tomto tématu popovídat na školení Návrh a používání MySQL databáze.
Diskuse
Postak:
Velmi zajimave a pekne, zajimalo by mne jestli existuje neake reseni pro pripad, kdy bych chtel napriklad tabulku knizek a u nich bych mel sloupec 'pujceno' a chci zjistit kolik mam celkem knizek, kolik jich je pujceno a kolik jeste ne:
SELECT
COUNT(*) AS 'celkem',
SUM(pujceno = 1) AS 'pujceno',
(COUNT(*) - SUM(pujceno = 1)) AS 'nepujceno'
FROM knihy;
Opravdu se musi takto slozite psat dotaz ? Nepocita pote sqlko vse znovu nebo je tak chytre ze jsi to jiz pamatuje ?
Dekuji .]
nepujceno nemusíš rátať v dotaze, hádam to vieš odpočítať i v PHP...
Jakub: super finta.
Postak:
ja vim ale jde to jestli jestli muzez tyhle veci resit rovnou v databazi, muzez mit pripady kdy to pote prohanet jeste cyklem (pri group by) je zbytecne..
Rony:
tahle finta je dobra osobne pouzivam misto SUM COUNT a u nej toho ze nezapocitava NULL hodnotu
COUNT(IF(sloupec = hodnota, 1, NULL))
Llaik:
Co kdyz je podminka nad indexovanym sloupcem, pouzije se v tomto pripade index?
Protoze pokud se nepletu, tak v mysql je count(*) extremne rychly, protoze danou informaci bere z hlavicky tabulky a tedy ve skutecnosti nic nepocita.
A nasledny druhy dotaz, ktery provede omezujici podminku pomoci indexu, by byl take vcelku schopny.
Takto na prvni pohled mam strach, ze se index nepouzije a mam sice jen jeden dotaz, ve vysledku ale pomalejsi. Nebo se pletu? :)
Tvá obava je oprávněná - index se sice použije, ale jen pro rychlejší přečtení všech dat. Porovnání se potom dělá u každého záznamu zvlášť.
Trik se tedy hodí jen na menší tabulky nebo pro jednorázové operace.
Andrew:
Pěkný Jakubův příklad, ale beru ho spíše jako inspirační, neboť z praxe vím, že mnoho jednoduchých dotazů je podstatně rychlejších než jeden hezký, ale složitý, jak zde poznamenal Llaik.
Nicméně je pěkné vidět, že to pomocí SQL jde a minimálně takový dotaz využiju při přístupu přes konzoli. :-)
PAtrik:
Pekny trik. Napadlo ma ci neexistuje trik aj pre zistenie poctu zaznamov selectu, ktoy ma limit. Teda mam nejaky select s podmienkamy a vysledok chcem listovat, tak vyberiem len 1. stranku, a potrebujem este zistit pocet zaznamov vyhovujuci selectu bez toho limitu. Momentalne to riesim druhym selectom na pocet, ale mozno tu by sa nejaky trik oplatil.
Pavel:
V případě že budu mít více podmínek existuje i nějaké elegantnější řešení než použít spoustu if podmínek ?
Diskuse je zrušena z důvodu spamu.