简体   繁体   English

Rails + Postgres查询满足具有唯一关联ID的条件的所有记录

[英]Rails + Postgres query for all records that meet a criteria with a unique association ID

I have some code like this: 我有一些这样的代码:

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

Which fills my logs with a few screens worth of queries like these: 这使我的日志充满了一些类似以下查询的屏幕:

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"
  ...

(Activity has a default scoped order of id DESC ) (活动的默认作用域范围为id DESC

So I'm hoping there is a way to fetch all the activities I need per timestamp in a single query. 因此,我希望有一种方法可以在单个查询中获取每个时间戳所需的所有活动。 This would reduce my number of from activity_count * 2 to simply 2 . 这会将我的数量从activity_count * 2减少到2

Here's what I tried, but I don't think distinct is properly being used here. 这是我尝试过的方法,但我认为此处没有正确使用distinct

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

Which spews out: 哪个喷涌而出:

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):

What I mean to do here is to say: give me all activities that have a stage_id in an array of stages , where the created_at date is nearest to (without going over) a timestamp. 我的意思做的,是在说:给我说有一个所有活动stage_id在数组stages ,其中created_at日期最接近(而不超过)时间戳。 What I want to get back is a single activity record for every stage in stages . 我想回去是在每一个阶段,一个单一的活动记录stages

Is it possible to do this in 1 query rather than stages.count queries? 是否可以在1查询中而不是stages.count查询中执行此stages.count

By taking a look at your error... 通过查看您的错误...

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

...I got to this Stack Overflow post . ...我到了这个Stack Overflow帖子

You need to include 'account_id' in your order function somewhere. 您需要在订单功能的某处添加“ account_id”。

So I think you should be able to do... 所以我认为您应该可以...

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM