SQL の使用に関するいくつかの重要なポイント:
- WHERE 句では列の別名を使用できませんが、HAVING 句では使用できます。それがあなたが得たエラーの原因です。
- 相関サブクエリを使用するよりも、JOIN と GROUP BY を使用した方がカウントを効率的に行うことができます。それははるかに高速になります。
- グループをフィルタリングするには、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: コメントの質問:
違いは、グループをグループごとに 1 つの行に減らすWHERE
前に、句が行で評価されることです。句は、グループが形成された後に評価されますGROUP BY
。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;
上記のようなクエリを使用すると、select-list の式はすべての行に対して計算されますが、条件のためにほとんどの結果が破棄されHAVING
ます。ただし、以下のクエリは、条件に一致する単一の行WHERE
に対してのみ式を計算します。
SELECT <expensive expressions>
FROM t1
WHERE primaryKey = 1234;
要約すると、クエリは一連の手順に従ってデータベース エンジンによって実行されます。
- によって生成された行を含む、テーブルから行のセットを生成し
JOIN
ます。
- 行のセットに対して条件を評価
WHERE
し、一致しない行を除外します。
- 行セットのそれぞれについて、select-list の式を計算します。
- 列のエイリアスを適用します (これは別の手順です。つまり、select-list の式でエイリアスを使用することはできません)。
GROUP BY
句に従って、グループをグループごとに 1 つの行に圧縮します。
- グループに対する条件を評価
HAVING
し、一致しないグループを除外します。
ORDER BY
句に従って、結果を並べ替えます。