SQLの使用に関するいくつかの重要なポイント:
- WHERE句では列エイリアスを使用できませんが、HAVING句では使用できます。それがエラーの原因です。
- 相関サブクエリを使用するよりも、JOINとGROUPBYを使用した方がカウントを向上させることができます。はるかに高速になります。
- HAVING句を使用してグループをフィルタリングします。
このクエリの書き方は次のとおりです。
SELECT t1.id, COUNT(t2.id) AS num_things
FROM t1 JOIN t2 USING (id)
GROUP BY t1.id
HAVING num_things = 5;
このクエリはJOINをスキップできることに気付きました Charles Bretanaのソリューションのように、t1を使用します。ただし、クエリにt1の他の列を含めることをお勧めします。
Re:コメントの質問:
違いは、WHERE 句は、GROUP BYの前の行で評価されます グループをグループごとに1行に減らします。 HAVING グループが形成された後、句が評価されます。したがって、たとえば、COUNT()を変更することはできません。 HAVINGを使用したグループの;グループ自体のみを除外できます。
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;
上記のクエリでは、WHERE 条件に一致する行のフィルター、およびHAVING 少なくとも5つのカウントを持つグループのフィルター。
ほとんどの人が混乱するのは、GROUP BYがない場合です。 句なので、そうです HAVINGのように およびWHERE 交換可能です。
WHERE 選択リストの式の前に評価されます。 SQL構文では選択リストが最初に配置されるため、これは明らかではない場合があります。したがって、WHEREを使用すると、コストのかかる計算を大幅に節約できます。 行を制限します。
SELECT <expensive expressions>
FROM t1
HAVING primaryKey = 1234;
上記のようなクエリを使用する場合、選択リストの式はすべての行に対して計算されます。 、HAVINGのため、ほとんどの結果を破棄するだけです 調子。ただし、以下のクエリは、単一行の式のみを計算します。 WHEREと一致する 状態。
SELECT <expensive expressions>
FROM t1
WHERE primaryKey = 1234;
要約すると、クエリは一連の手順に従ってデータベースエンジンによって実行されます。
-
JOINによって生成された行を含め、テーブルから行のセットを生成します 。 WHEREを評価する 行のセットに対する条件、一致しない行を除外します。- 行セット内のそれぞれの選択リストで式を計算します。
- 列エイリアスを適用します(これは別の手順であるため、選択リストの式でエイリアスを使用することはできません)。
-
GROUP BYに従って、グループをグループごとに1行に凝縮します。 条項。 -
HAVINGを評価する グループに対する条件、一致しないグループを除外します。 -
ORDER BYに従って結果を並べ替えます 条項。