SQL HAVING klauzule je speciálním druhem SQL příkazu, který se chová podobně jako jako WHERE. To znamená, že pomocí ní definujeme omezující podmínku při vyhledávání nebo manipulaci s tabulkami. Mezi oběma klauzulemi jsou ale významné rozdíly. Pojďmě si tedy SQL HAVING vs WHERE odlišnosti popsat.
Pořadí v SQL skriptu
- SELECT
- FROM
- WHERE
- GROUP BY
- HAVING
- ORDER BY
Proč existují 2 klauzule pro definování podmínek? Odpověď leží v článku logického zpracování dotazu. Tam vidíme, že pořadí zpracování skriptu je následující:
- FROM,
- WHERE,
- GROUP BY,
- HAVING,
- SELECT,
- ORDER BY
Dobře si prohlédněte pořadí zpracování. Z výše uvedeného plyne, že např. agregační operace (GROUP BY) je zpracována až po vyhodnocení podmínek ve WHERE klauzuli. Kam bychom napsali do SQL skriptu podmínku, která je založena na agregaci SUMA(něco)>0? Museli bychom podmínku vyhodnotit na dvakrát (přes vnořený dotaz, CTE a podobně). Naštěstí to není potřeba a můžeme pro podobné podmínky využít klauzuli HAVING.
Shrnutí:
- Do WHERE píšeme podmínky, které pracují s tady v původní (nezagregované podobě).
- Agregační podmínka se zadává do HAVING, protože když přijde tato klauzule v rámci vyhodnocení skriptu na řadu, je SUMA(něčeho) už spočítaná a lze ji použít pro vyhodnocení podmínky
HAVING používáme hlavně k zadání podmínky na základě agregační funkce
Syntaxe klauzule HAVING
SELECT [Sloupec1],[Sloupec2], AgregacniFunkce([Sloupec3]) AS Castka
FROM Tabulka
WHERE Podminka
GROUP BY [Sloupec1],[Sloupec2]
HAVING AgregacniFunkce([Sloupec3]) <operator> Podminka
Příklad SQL skriptu:
Tabulka [FactInternetSales] má spoustu polí jak je vidět z obrázku, ale my budeme pracovat pouze se 2-ma poli:
- Datum [OrderDate]
- Částka [SalesAmount]
Podobně jako v úkolu v článku o GROUP BY budeme chtít agregovat částku podle datumů a výsledek tentokrát seřadíme vzestupně. Navíc ale budeme chtít zobrazit pouze datumy, kde součet prodejů je větší než 80 000. Použijeme k tomu:
- agregační funkci SUM() v klauzuli SELECT
- GROUP BY
- HAVING
- ORDER BY
Záměna SQL HAVING vs WHERE – Pojďme se podívat co se stane když klauzule zaměníme
Co se stane když napíšeme podmínku založenou na agregační funkci do WHERE:
SELECT [OrderDate] AS Datum
,SUM([SalesAmount]) AS Soucet
FROM [AdventureWorksDW2012].[dbo].[FactInternetSales]
WHERE SUM([SalesAmount])>80000
GROUP BY [OrderDate]
ORDER BY [OrderDate]
Jak napsat skript s HAVING správně?
Místo where použijeme HAVING:
SELECT [OrderDate] AS Datum
,SUM([SalesAmount]) AS Soucet
FROM [AdventureWorksDW2012].[dbo].[FactInternetSales]
GROUP BY [OrderDate]
HAVING SUM([SalesAmount])>80000
ORDER BY [OrderDate];
Výsledek je OK:
Kombinace SQL HAVING vs WHERE
WHERE a HAVING se dá samozřejmě kombinovat. Budeme-li chtít například pouze Datumy od 1.1.2007 do 31.12.2007 kde součet tržeb >80 000, tak podmínku na datum uvedeme do WHERE a podmínku na agregaci do having, příklad zde:
Skript proběhl úspěšně bez chybové hlášky a vidíme, že mezi 1.1.2007 a 31.12.2007 nebyl ani jeden den, kde součet tržeb byl větší než 80 000.