3

短いバージョン:このクエリをsqueelで作成するにはどうすればよいですか?

SELECT OneTable.*, my_count
FROM   OneTable JOIN (
  SELECT DISTINCT one_id, count(*) AS my_count
  FROM   AnotherTable
  GROUP BY one_id
) counts
ON OneTable.id=counts.one_id

長いバージョン:rocket_tagは、モデルに単純なタグ付けを追加するgemです。メソッドを追加しますtagged_with。私のモデルがUser、IDと名前で、を呼び出すことができると仮定しUser.tagged_with ['admin','sales']ます。内部的には、次のsqueelコードを使用します。

select{count(~id).as(tags_count)}
.select("#{self.table_name}.*").
joins{tags}.
where{tags.name.in(my{tags_list})}.
group{~id}

このクエリを生成します:

SELECT count(users.id) AS tags_count, users.*
  FROM users INNER JOIN taggings
    ON taggings.taggable_id = users.id
   AND taggings.taggable_type = 'User'
  INNER JOIN tags
    ON tags.id = taggings.tag_id
  WHERE tags.name IN ('admin','sales')
  GROUP BY users.id

一部のRDBMSはこれに満足していますが、postgresは次のように不平を言っています。

ERROR: column "users.name" must appear in the GROUP BY
clause or be used in an aggregate function

クエリを書くためのより快適な方法は次のようになると思います。

SELECT users.*, tags_count FROM users INNER JOIN (
  SELECT DISTINCT taggable_id, count(*) AS tags_count
    FROM taggings INNER JOIN tags
      ON tags.id = taggings.tag_id
    WHERE tags.name IN ('admin','sales')
    GROUP BY taggable_id
  ) tag_counts
  ON users.id = tag_counts.taggable_id

squeelを使ってこれを表現する方法はありますか?

4

1 に答える 1

2

Squeelについてはわかりませんが、PostgreSQLをアップグレードすることでエラーを修正できます。

一部のRDBMSはこれに満足していますが、postgresは次のように不平を言っています。

エラー:列 "users.name"は、GROUP BY句に含めるか、集計関数で使用する必要があります

PostgreSQL 9.1以降、GROUP BYに主キーをリストすると、このテーブルの追加の列をスキップして、SELECTリストで引き続き使用できます。バージョン9.1のリリースノートには次のように書かれています。

主キーがGROUPBY句で指定されている場合、クエリターゲットリストで非GROUPBY列を許可する


ところで、代替クエリは単純化でき、追加DISTINCTは冗長になります。

SELECT o.*, c.my_count
FROM   onetable o
JOIN (
  SELECT one_id, count(*) AS my_count
  FROM   anothertable
  GROUP  BY one_id
) c ON o.id = counts.one_id
于 2012-03-19T07:26:35.513 に答える