Techioz Blog

group() および sum() クエリを実行して、アクティブなレコードのグループ化に使用された合計と列以上のものを返す方法

概要

has_and_belongs_to_many によって関連付けられたカテゴリ (名前、画像データ) と経費 (名前、金額、日付) の 2 つのテーブルがあります (経費には多くのカテゴリがあり、カテゴリには多くの経費があります)。すべてのカテゴリとそれに関連付けられた経費を選択し、それらをカテゴリ ID でグループ化し、カテゴリ テーブルの他の列 (名前と画像データ) も返すアクティブ レコード クエリを作成したいと考えています。

私が試してみました

Category.includes(:expenses).group('categories.id').sum(:amount)

しかし、私が得たのは

{4=>0.75e5, 6=>0.18e6, 5=>0.0}

これはカテゴリテーブルの列を返しません。

k = Category.includes(:expenses).group('categories.id').select('categories.*, SUM(expenses.amount) AS total_amount').pluck('categories.id', 'categories.name', 'total_amount')

しかし、列名「total_amount」が不明であるというエラーが表示されます。

  1. また、返したいカテゴリテーブルのすべての列に基づいて結果をグループ化しようとしましたが、これを行うことでクエリが遅くなっていると思います。
Category.includes(:expenses).group('id', 'name', 'image_data').sum(:amount)

解決策

返された列をグループ化に含める必要があるため、3 番目のオプションが機能するはずです。これは SQL での集計の仕組みです。グループ化してカウント/合計する場合、グループ化された列ごとに 1 行しか存在しないため、グループ化されていない他の列を含めることはできません。