Navicatブログ

集計フィールドをHAVING句でフィルタリングする Oct 8, 2024 by Robert Gravelle

SQLクエリをある程度書いている方であれば、WHERE句にはかなり精通しているのではないでしょうか。WHERE句は集計フィールドには影響しませんが、集計値に基づいてレコードをフィルタリングする方法があり、その目的でHAVING句が用いられます。このブログでは、HAVING句の仕組みと、SELECTクエリでの使用方法の例をいくつか紹介します。

集約とHAVING句

集約は、通常、グループ化と組み合わせて使用されます。SQLでは、GROUP BY句を使用して実現します。集約とグループ化を組み合わせることで、データに対する高レベルな洞察を得ることができます。例えば、eコマース企業は、一定期間の売上を追跡したい場合があります。

多くの場合、データセット全体にGROUP BY句を適用したくない場合があります。このような場合、GROUP BYコマンドと条件付きHAVING句を一緒に使用して、不要な結果をフィルタリングすることができます。WHERE句と同様に、HAVING句は1つ以上のフィルター条件を指定しますが、グループまたは集約に対して指定します。そのため、HAVING句は常にWHERE句とGROUP BY句の後、(オプションの)ORDER BY句の前に配置されます。

SELECT column_list
FROM table_name
WHERE where_conditions
GROUP BY column_list
HAVING having_conditions
ORDER BY order_expression

実用的な例

HAVING句の動作をよりよく理解するために、Sakila Sample Databaseに対していくつかのSELECTクエリを実行してみましょう。

最初のクエリは、レンタル回数の多い顧客が上位に表示されるように、上位の映画レンタル者を降順に並べ替えたものです。リストをある程度短くするために、HAVING句を使用してレンタル回数が3回未満の顧客を削除します。

SELECT
  c.customer_id,
  c.first_name,
  c.last_name,
  COUNT(r.rental_id) AS total_rentals
FROM 
  customer AS c
    LEFT JOIN rental AS r ON c.customer_id = r.customer_id
GROUP BY c.customer_id
HAVING total_rentals >= 3
ORDER BY total_rentals DESC;

Navicat Premium でのクエリと最初のページの結果を以下に示します。

top movie renters (89K)

これらのレンタル回数から判断すると、リストをさらに絞り込むことができそうですね!

WHERE句とHAVING句の両方を使用した行のフィルタリング

GROUP BY句とORDER BY句がクエリの処理の異なる時点で適用されるのと同様に、WHERE句とHAVING句も異なる時点で適用されます。そのため、グループ化と集約の前後で結果をフィルタリングするために、両方をクエリに含めることができます。たとえば、WHERE句を追加して、結果を特定の年の前半に制限することができます。

SELECT
  c.customer_id,
  c.first_name,
  c.last_name,
  COUNT(r.rental_id) AS total_rentals
FROM 
  customer AS c
    LEFT JOIN rental AS r ON c.customer_id = r.customer_id
WHERE r.rental_date BETWEEN '2005-01-01' AND '2005-06-30'
GROUP BY c.customer_id
HAVING total_rentals >= 3
ORDER BY total_rentals DESC;

ここでも、上記のクエリとNavicat Premium での最初のページの結果を以下に示します。

top movie renters for first half of 2005 (96K)

複数の条件の組み合わせ

WHERE句がANDキーワードとORキーワードを使用して複数の条件をサポートしているのと同様に、HAVING句も複数の条件をサポートしています。たとえば、HAVING句を以下のように変更することで、レンタル回数が特定の範囲内にある顧客を見つけることができます。

HAVING total_rentals >= 3 AND total_rentals <= 10

まとめ

今日のブログでは、HAVING句を使用してグループ化および集計されたフィールドをフィルタリングする方法を学びました。

Navicat Premium に興味がありますか?評価目的であれば、14日間完全に無料で試用できます!

ブログのアーカイブ
シェア