You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

查询近9周未参加活动的跑者:ActiveRecord Scope关联查询问题

问题分析与解决建议

你的Scope逻辑存在核心问题,导致查询无结果:

  • 你先用LEFT JOIN关联attendances试图获取无参与记录的跑者,但紧接着用**内连接(INNER JOIN)**关联happenings。当attendances.id IS NULL时,attendances.happening_id也为NULL,内连接会自动过滤掉所有NULL匹配的记录,最终返回空集。

下面提供两种可行的解决方案:

方案一:使用NOT EXISTS子查询(推荐)

这种方式逻辑清晰、性能更优,直接筛选出"近9周内无任何活动参与记录"的跑者:

scope :inactive_for_nine_weeks, -> {
  where.not(
    id: Attendance.joins(:happening)
                  .where("happenings.started_at > ?", 9.weeks.ago)
                  .select(:runner_id)
  )
}

对应的SQL逻辑是:找出所有跑者,排除近9周内有活动参与记录的跑者。

方案二:修正JOIN关联逻辑

如果坚持用JOIN方式,需要把happenings也改为左连接,同时调整条件判断:

scope :inactive_for_nine_weeks, -> {
  left_joins(:attended_happenings)
    .group("runners.id")
    .having(
      "COUNT(attendances.id) = 0 OR MAX(happenings.started_at) <= ?", 
      9.weeks.ago
    )
}

这种方式通过分组聚合判断跑者的活动参与情况,逻辑相对复杂,不如子查询直观。

验证方法

可以先单独查询近9周有活动参与的跑者ID集合,确认数据是否正确:

active_runner_ids = Attendance.joins(:happening)
                               .where("happenings.started_at > ?", 9.weeks.ago)
                               .pluck(:runner_id)
                               .uniq

再对比Runner.where.not(id: active_runner_ids)的结果,验证是否符合预期。

内容的提问来源于stack exchange,提问作者DavidM

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 04:07:39