fumi blog

現役エンジニアが解説!ActiveRecordでHAVING句を使う方法とは?

本記事では、Ruby on RailsのActiveRecordでhaving句を実行する方法について解説します。

having句とは?

HAVING句は、GROUP BY句でグループ化されたレコードに対して、条件を適用するためのSQLの機能です。
例えば、以下のような月ごとの売り上げを表すテーブルを考えてみましょう。

sales
+----+---------+-------+
| id |  month  | sales |
+----+---------+-------+
|  1 | 202201  |  100  |
|  2 | 202201  |  200  |
|  3 | 202201  |  300  |
|  4 | 202202  |  150  |
|  5 | 202202  |  250  |
|  6 | 202203  |  400  |
+----+---------+-------+


このテーブルを、月ごとにグループ化して、売上が合計500以上の月だけを取得するには、以下のようなSQLを記述することができます。

SELECT month, SUM(sales) as total_sales
FROM sales
GROUP BY month
HAVING SUM(sales) >= 500;


上記のSQLでは、まずsalesテーブルをmonthでグループ化して、売上を合計しています。次に、HAVING句で、合計売上が500以上の月だけを取得しています。結果は以下のようになります。

+--------+-------------+
| month  | total_sales |
+--------+-------------+
| 202201 |     600     |
| 202203 |     400     |
+--------+-------------+


このように、HAVING句は、グループ化されたレコードに対して条件を適用するための非常に有用なSQLの機能です。

ActiveRecordでHaving句を使おう

ActiveRecordでは、havingメソッドを使用してHAVING句を表現できます。たとえば、先ほどのSQLクエリをActiveRecordの形式で書くと以下のようになります。

Sales.group(:month).having("SUM(sales) >= ?", 500).select("month, SUM(sales) as total_sales")


まずgroupメソッドでグループ化するカラムを指定します。次に、havingメソッドで、「合計売上が500以上の月」を取得する条件を指定します。最後に、selectメソッドで、monthと売上の合計を表示します。

上記の出力結果は以下のようにhashの形で帰ってきます

[{:month=>"202201", :total_sales=>600}, {:month=>"202203", :total_sales=>400}]


まとめ

今回は、ActiveRecordを使用してSQLのHAVING句を使う方法について解説しました。ActiveRecordをうまく使うと、このようにSQLを直接書くことなくデータベースとやりとりできます。安全なアプリケーションを作るために、ぜひ1つのテクニックとして覚えておきましょう。