Několik důležitých bodů o používání SQL:
- Aliasy sloupců nelze použít v klauzuli WHERE, ale v klauzuli HAVING ano. To je příčina vaší chyby.
- Počítání můžete provést lépe pomocí JOIN a GROUP BY než pomocí korelovaných poddotazů. Bude to mnohem rychlejší.
- K filtrování skupin použijte klauzuli HAVING.
Tento dotaz bych napsal takto:
SELECT t1.id, COUNT(t2.id) AS num_things
FROM t1 JOIN t2 USING (id)
GROUP BY t1.id
HAVING num_things = 5;
Uvědomuji si, že tento dotaz může přeskočit JOIN
s t1, jako v řešení Charlese Bretany. Předpokládám však, že byste mohli chtít, aby dotaz zahrnoval některé další sloupce z t1.
Re:otázka v komentáři:
Rozdíl je v tom, že WHERE
klauzule se vyhodnocuje na řádcích před GROUP BY
redukuje skupiny na jeden řádek na skupinu. HAVING
klauzule se hodnotí po vytvoření skupin. Nemůžete tedy například změnit COUNT()
skupiny pomocí HAVING
; můžete vyloučit pouze samotnou skupinu.
SELECT t1.id, COUNT(t2.id) as num
FROM t1 JOIN t2 USING (id)
WHERE t2.attribute = <value>
GROUP BY t1.id
HAVING num > 5;
Ve výše uvedeném dotazu WHERE
filtry pro řádky odpovídající podmínce a HAVING
filtry pro skupiny, které mají alespoň pět.
Bod, který většině lidí způsobuje zmatek, je, když nemají GROUP BY
klauzule, tak se zdá jako HAVING
a WHERE
jsou zaměnitelné.
WHERE
je vyhodnocen před výrazy ve výběrovém seznamu. To nemusí být zřejmé, protože syntaxe SQL klade výběrový seznam na první místo. Použitím WHERE
si tedy můžete ušetřit spoustu drahých výpočtů pro omezení řádků.
SELECT <expensive expressions>
FROM t1
HAVING primaryKey = 1234;
Pokud použijete dotaz jako výše, výrazy ve výběrovém seznamu se vypočítají pro každý řádek , pouze zahodit většinu výsledků kvůli HAVING
stav. Dotaz níže však vypočítá výraz pouze pro jeden řádek odpovídající WHERE
podmínka.
SELECT <expensive expressions>
FROM t1
WHERE primaryKey = 1234;
Abychom to shrnuli, dotazy spouští databázový stroj podle série kroků:
- Generujte sadu řádků z tabulek, včetně všech řádků vytvořených
JOIN
. - Vyhodnoťte
WHERE
podmínky vůči sadě řádků, odfiltrování řádků, které se neshodují. - Vypočítejte výrazy ve výběrovém seznamu pro každý v sadě řádků.
- Použít aliasy sloupců (všimněte si, že se jedná o samostatný krok, což znamená, že nemůžete používat aliasy ve výrazech ve výběrovém seznamu).
- Zhustit skupiny na jeden řádek na skupinu podle
GROUP BY
doložka. - Vyhodnoťte
HAVING
podmínky vůči skupinám, odfiltrování skupin, které se neshodují. - Seřaďte výsledek podle
ORDER BY
doložka.