根据关联模型的属性的最大值返回所有实例

Return all instances based on the max of an attribute of an associated model

提问人:DavidM 提问时间:9/15/2023 更新时间:9/15/2023 访问量:42

问:

意识到标题根本不好。从本质上讲,我有一个与 有关系的模型。我想返回所有没有任何时间段的 TaskReferral 实例,这些实例的日期超过给定日期TaskReferralhas_manyTimeSlotstarted_at

class MissionReferral < TaskReferral
  has_many :time_slots
end

class TimeSlot
  belongs_to :booking, polymorphic: true
end

我在'mission_referral.rb中尝试这样的事情:

scope :with_no_timeslots_after, lambda { |date|
    from(
      <<~SQL
        (
          SELECT *
          FROM task_referrals tr
          JOIN (
            SELECT booking_id, booking_type, max(started_at) as started_at
            FROM time_slots AS ts
            GROUP by booking_id, booking_type
          ) as latest_time_slot
          ON tr.id =  latest_time_slot.booking_id
          AND latest_time_slot.booking_type = 'TaskReferral'
          WHERE started_at < #{date.to_date}
        )
      SQL
    )
  }

但是当我跑步时,我得到:MissionReferral.with_no_timeslots_after(1.day.from_now)

MissionReferral Load (0.9ms)  SELECT "task_referrals".* FROM (
  SELECT *                                                                                                           
  FROM task_referrals tr                                                                                             
  JOIN (                                                                                                             
    SELECT booking_id, booking_type, max(started_at) as started_at                                                   
    FROM time_slots AS ts                                                                                            
    GROUP by booking_id, booking_type                                                                                
  ) as latest_time_slot                                                                                              
  ON tr.id =  latest_time_slot.booking_id                                                                            
  AND latest_time_slot.booking_type = 'TaskReferral'                                                                 
  WHERE started_at < 2023-09-16                                                                                      
)                                                                                                                    
 WHERE "task_referrals"."type" = $1  [["type", "MissionReferral"]]                                                   
(Object doesn't support #inspect)     

或者如果我运行,我会得到:MissionReferral.with_no_timeslots_after(1.day.from_now).count

MissionReferral Count (1.1ms)  SELECT COUNT(*) FROM (
  SELECT *                                                                                                           
  FROM task_referrals tr                                                                                             
  JOIN (                                                                                                             
    SELECT booking_id, booking_type, max(started_at) as started_at                                                   
    FROM time_slots AS ts                                                                                            
    GROUP by booking_id, booking_type                                                                                
  ) as latest_time_slot                                                                                              
  ON tr.id =  latest_time_slot.booking_id                                                                            
  AND latest_time_slot.booking_type = 'TaskReferral'                                                                 
  WHERE started_at < 2023-09-16                                                                                      
)                                                                                                                    
 WHERE "task_referrals"."type" = $1  [["type", "MissionReferral"]]                                                   
/home/dave-gg/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/activerecord-7.0.4.2/lib/active_record/connection_adapters/postgresql_adapter.rb:768:in `exec_params': PG::SyntaxError: ERROR:  subquery in FROM must have an alias (ActiveRecord::StatementInvalid)
LINE 1: SELECT COUNT(*) FROM (
                             ^
HINT:  For example, FROM (SELECT ...) [AS] foo.
/home/dave-gg/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/activerecord-7.0.4.2/lib/active_record/connection_adapters/postgresql_adapter.rb:768:in `exec_params': ERROR:  subquery in FROM must have an alias (PG::SyntaxError)
LINE 1: SELECT COUNT(*) FROM (
                             ^
HINT:  For example, FROM (SELECT ...) [AS] foo.

奇怪的是,我可以让查询在连接到数据库的 SQL 编辑器中运行,所以不要以为我离得太远了。任何帮助将不胜感激。

SQL Ruby-on-Rails PostgreSQL ActiveRecord

评论

2赞 engineersmnky 9/15/2023
这似乎很尴尬。似乎以下内容应该有效TaskReferral.where(id: TimeSlot.where(booking_type: 'TaskReferral').select(:booking_id).group(:booking_id).having(TimeSlot.arel_table[:started_at].maximum.lt(date))))
0赞 Jignesh Gohel 9/15/2023
stackoverflow.com/a/16918028/936494 参考以下帖子,stackoverflow.com/a/28085614/936494 它们是否可以引发任何实现预期结果的想法。谢谢。
0赞 DavidM 9/15/2023
谢谢@engineersmnky这正是我要找的。我的查询技巧不是最好的。如果你想把它作为一个答案,我会验证它

答: 暂无答案