【发布时间】:2017-02-08 23:52:43
【问题描述】:
我有一些这样的代码:
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 * 2 减少到简单的2。
这是我尝试过的,但我认为 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):
我的意思是说:给我所有在stages 数组中具有stage_id 的活动,其中created_at 日期最接近(不超过)时间戳。我想要返回的是stages 中每个阶段的单个活动记录。
是否可以在 1 查询而不是 stages.count 查询中执行此操作?
【问题讨论】:
标签: sql ruby-on-rails ruby postgresql distinct