QA@IT
«質問へ戻る

質問を投稿

GROUP BYを使ったクエリをArel (ActiveRecord) で書くには?

Railsで習作アプリを作っています。PostgreSQLを使っていて、以下のようなスキーマがあります。日付と距離(水泳の記録です)、及びコメントを記録するだけのものです。

mswim-development-# \d swims
                                     Table "public.swims"
   Column   |            Type             |                     Modifiers                      
------------+-----------------------------+----------------------------------------------------
 id         | integer                     | not null default nextval('swims_id_seq'::regclass)
 length     | integer                     | 
 swam_at    | date                        | 
 note       | text                        | 
 created_at | timestamp without time zone | not null
 updated_at | timestamp without time zone | not null
Indexes:
    "swims_pkey" PRIMARY KEY, btree (id)

月ごとの合計距離を出したいのですが、以下のようなSQLをRailsから発行したいのですが、やり方が分かりません。

mswim-development-# SELECT to_char(swam_at, 'yyyy-mm') AS month, sum(length) FROM "swims" GROUP BY month ORDER BY month;
  month  |  sum
---------+-------
 2012-01 |  3400
 2012-02 |  2800
 2012-03 |  3800
 2012-04 |  6150
 2012-05 | 12800
 2012-06 | 15500
 2012-07 | 12200
(7 rows)

こんな感じでHashを返してくれるかなと書いてみたのは、

@months = Swim.group("to_char(swam_at, 'yyyymm')").sum(:length)

ですが、

> Swim.group("to_char(swam_at, 'yyyymm')").sum(:length)
(0.9ms)  SELECT SUM("swims"."length") AS sum_length, to_char(swam_at, 'yyyymm') AS to_char_swam_at_yyyymm FROM "swims" GROUP BY to_char(swam_at, 'yyyymm') ORDER BY swam_at DESC

PG::Error: ERROR:  column "swims.swam_at" must appear in the GROUP BY clause or be used in an aggregate function

とエラーで怒られます。何を間違えているのかお分かりの方がいれば、教えていただけませんでしょうか。

Railsで習作アプリを作っています。PostgreSQLを使っていて、以下のようなスキーマがあります。日付と距離(水泳の記録です)、及びコメントを記録するだけのものです。

```
mswim-development-# \d swims
                                     Table "public.swims"
   Column   |            Type             |                     Modifiers                      
------------+-----------------------------+----------------------------------------------------
 id         | integer                     | not null default nextval('swims_id_seq'::regclass)
 length     | integer                     | 
 swam_at    | date                        | 
 note       | text                        | 
 created_at | timestamp without time zone | not null
 updated_at | timestamp without time zone | not null
Indexes:
    "swims_pkey" PRIMARY KEY, btree (id)
```

月ごとの合計距離を出したいのですが、以下のようなSQLをRailsから発行したいのですが、やり方が分かりません。

```
mswim-development-# SELECT to_char(swam_at, 'yyyy-mm') AS month, sum(length) FROM "swims" GROUP BY month ORDER BY month;
  month  |  sum
---------+-------
 2012-01 |  3400
 2012-02 |  2800
 2012-03 |  3800
 2012-04 |  6150
 2012-05 | 12800
 2012-06 | 15500
 2012-07 | 12200
(7 rows)
```

こんな感じでHashを返してくれるかなと書いてみたのは、

```ruby
@months = Swim.group("to_char(swam_at, 'yyyymm')").sum(:length)
```

ですが、

```
> Swim.group("to_char(swam_at, 'yyyymm')").sum(:length)
(0.9ms)  SELECT SUM("swims"."length") AS sum_length, to_char(swam_at, 'yyyymm') AS to_char_swam_at_yyyymm FROM "swims" GROUP BY to_char(swam_at, 'yyyymm') ORDER BY swam_at DESC

PG::Error: ERROR:  column "swims.swam_at" must appear in the GROUP BY clause or be used in an aggregate function
```

とエラーで怒られます。何を間違えているのかお分かりの方がいれば、教えていただけませんでしょうか。