Rails 3 DISTINCT QUERY
拥有User,UserBadge和Badge表。 它们通过has_many连接。 用户可以拥有多个相同的徽章,但我想查询唯一列表。
@user.badges.select("DISTINCT id").order("created_at DESC")
这是一个错误:
SQLite3::SQLException: near "DISTINCT": syntax error:
什么是正确的语法?
编辑:添加整个错误
SQLite3::SQLException: near "DISTINCT": syntax error: SELECT "badges".*, DISTINCT badges.id FROM "badges" INNER JOIN "userbadges" ON "badges".id = "userbadges".badges_id WHERE (("userbadges".user_id = 1))
可能是select和distinct之间的逗号吗?
在SELECT之后,DISTINCT需要是直的
SELECT DISTINCT(badges.id), "badges".* FROM "badges" INNER JOIN "userbadges" ON "badges".id = "userbadges".badges_id WHERE (("userbadges".user_id = 1))
尝试:
@user.select("DISTINCT(badges.id), badges.*").badges.order("badges.created_at DESC")
PostgreSQL要求您拥有distinct字段的订单声明:
@user.select("DISTINCT(badges.id), badges.*").badges.order("badges.id").order("badges.created_at DESC")
可以尝试使用组
@user.badges.group(:id)
组
:uniq => true
关于协会。 或者仅为用户的唯一徽章创建单独的关联。
http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html#method-i-has_many
就像是
Class User < ActiveRecord::Base has_many :user_badges has_many :badges, :through => :user_badges has_many :unique_badges, :through => :user_badges, :source => :badges, :uniq => true #untested end
试试这个
@user.badges.select("DISTINCT(badges.id)").order("badges.created_at DESC")
我也有类似的问题,也使用PostgreSQL。
我的代码看起来像这样:
User.find(2).devices.group('token')
这导致了一个错误:
Device Load (0.8ms) SELECT "devices".* FROM "devices" WHERE "devices"."user_id" = 2 GROUP BY token ActiveRecord::StatementInvalid: PG::Error: ERROR: column "devices.id" must appear in the GROUP BY clause or be used in an aggregate function
解:
将该行更改为:
User.find(2).devices.select('distinct token')
工作得很完美:
Device Load (1.3ms) SELECT distinct token FROM "devices" WHERE "devices"."user_id" = 2 => [#, # , # , # , # , # ]
更新:
对不起,我没有彻底阅读原始问题并且实际上已经回复了post中的另一篇post,抱怨#group方法不能使用PostgreSQL。 尽管如此,它仍然是一个有价值的答案,所以我会离开它。
至少有三种方法可以从用户那里获得唯一的徽章列表:
-
@user.badges.group(:id)
-
@user.badges.select("DISTINCT badges.*")
- 或者在
has_many :badges, :through
添加:uniq => true
has_many :badges, :through
当然,您也可以将您的order("badges.created_at DESC")
到查询中。
@user.badges.select("id").order("created_at DESC").uniq
这个对我有用。