Rails + Postgres查询满足具有唯一关联ID

时间:2017-02-08 23:52:44

标签: sql ruby-on-rails ruby postgresql distinct

我有一些像这样的代码:

stages.each do |stage|
  start_activity = stage.activities.where('created_at < ?', @start_time).first
  end_activity   = stage.activities.where('created_at < ?', @end_time).first
  # ...
end

使用以下几个屏幕填充我的日志:

Activity Load (0.3ms)  SELECT  "activities".* FROM "activities"
  WHERE "activities"."stage_id" = $1
  AND (created_at < '2017-01-31 08:00:00.000000')
  ORDER BY id DESC, "activities"."created_at" DESC
  LIMIT 1 
  [["stage_id", 11548]]
Activity Load (0.3ms)  SELECT  "activities".* FROM "activities"
  ...

(活动的默认范围顺序为id DESC

所以我希望有一种方法可以在单个查询中获取每个时间戳所需的所有活动。这会减少我从activity_count * 22的数量。

这是我尝试过的内容,但我不认为distinct已正确使用。

Activity
  .select('DISTINCT ON (stage_id) *')
  .where(stage: stages)
  .where('created_at < ?', @start_time)
  .reorder('id DESC')

哪个喷出:

ActiveRecord::StatementInvalid (PG::InvalidColumnReference: ERROR:  SELECT DISTINCT ON expressions must match initial ORDER BY expressions
LINE 1: SELECT DISTINCT ON (stage_id) * FROM "activities" WHERE "act...
                            ^
: SELECT DISTINCT ON (stage_id) * FROM "activities" WHERE "activities"."stage_id" IN (11548, 11549, <more ids snipped>, 12432, 12433) AND (created_at < '2017-01-31 08:00:00.000000')  ORDER BY id DESC):

我在这里要做的是说:给我stage_id数组中stages的所有活动,其中created_at日期距离最近(不会过去) )时间戳。我想要获得的是stages中每个阶段的单个活动记录。

是否可以在1查询而不是stages.count查询中执行此操作?

1 个答案:

答案 0 :(得分:0)

看看你的错误......

ERROR:  SELECT DISTINCT ON expressions must match initial ORDER BY expressions

......我得到this Stack Overflow post

您需要包含&#39; account_id&#39;在你的订单功能的某个地方。

所以我认为你应该能做到......

Activity
  .select('DISTINCT ON (stage_id)')
  .where(stage: stages)
  .where('created_at < ?', @start_time)
  .order(:stage_id, :created_at)