优雅的PostgreSQL Group for Ruby on Rails/ActiveRecord

dig*_*ost 11 postgresql activerecord ruby-on-rails

尝试使用PostgreSQL检索按日期分组的ActiveRecord对象数组.

更具体地说,我正在尝试翻译以下MySQL查询:

@posts = Post.all(:group => "date(date)", 
   :conditions => ["location_id = ? and published = ?", @location.id, true], 
   :order => "created_at DESC")
Run Code Online (Sandbox Code Playgroud)

我知道PostgreSQL对SQL标准的解释比MySQL更严格,因此这种类型的查询不起作用......并且已经阅读了StackOverflow和其他主题上的一些帖子 - 但它们似乎都没有关于这个问题的明确答案

我已经尝试过各种各样的查询组合,分组和不同的条款没有太大的乐趣 - 目前我有一个相当不优雅的黑客,虽然作品让我脸红时看着它.

使用Rails和PostgreSQL进行此类查询的正确方法是什么?(忽略肯定这应该在ActiveRecord级别抽象出来的事实)

Jas*_*red 14

您想在这里使用的PostgreSQL功能是DISTINCT ON.通过ActiveRecord进行此查询有两种基本方法.

第一种方法是只指定:select:order选项.当你有一个相当简单的查询没有:joins或时,这很有用:include.

Post.all(
  :select => 'DISTINCT ON (date::date) *',
  :order => 'date::date DESC, created_at DESC'
)
Run Code Online (Sandbox Code Playgroud)

如果您有一个更复杂的查询,其中ActiveRecord生成自己的SELECT子句,您可以使用子查询来选择目标记录.

Post.all(
  :joins => 'INNER JOIN (SELECT DISTINCT ON (date::date) id FROM posts ORDER BY date::date DESC, created_at DESC) x ON x.id = posts.id'
)
Run Code Online (Sandbox Code Playgroud)

请注意,根据您的数据,这可能比第一种方法慢一点.如果需要,我只会使用这种方法.务必使用类似生产的数据进行基准测试.