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

如何用ActiveRecord实现关联子查询的UPDATE操作?

用ActiveRecord实现关联子查询的UPDATE操作

你的这条SQL完全可以用ActiveRecord实现,下面针对你的疑问逐一解决:

1. 关联分组统计的子查询

你可以先构建分组统计的子查询,再通过joins方法将其作为临时表关联到users表。

先构建和原SQL逻辑一致的子查询:

counts_subquery = Post.select(:user_id, 'count(*) AS num').group(:user_id)

然后通过原生SQL片段关联这个子查询:

User.joins("JOIN (#{counts_subquery.to_sql}) AS counts ON users.id = counts.user_id")

如果想完全用ActiveRecord的Arel接口(避免字符串拼接),可以这么写:

users = User.arel_table
counts = counts_subquery.arel.as('counts')

join_clause = users.join(counts).on(users[:id].eq(counts[:user_id])).join_sources
User.joins(join_clause)

2. 为关联结果设置别名并比较值

当然可以设置别名,上面代码里的counts就是子查询临时表的别名,后续在where条件和update_all赋值里都能直接使用这个别名做值的比较。

完整的更新代码

结合起来,最终实现原SQL逻辑的ActiveRecord代码有两种写法:

方式一:混合原生SQL片段(直观易读)

counts_subquery = Post.select(:user_id, 'count(*) AS num').group(:user_id)

User.joins("JOIN (#{counts_subquery.to_sql}) AS counts ON users.id = counts.user_id")
    .where('users.publications != counts.num')
    .update_all('users.publications = counts.num')

方式二:纯Arel接口(更符合ActiveRecord风格)

counts_subquery = Post.select(:user_id, 'count(*) AS num').group(:user_id)
users = User.arel_table
counts = counts_subquery.arel.as('counts')

User.joins(users.join(counts).on(users[:id].eq(counts[:user_id])).join_sources)
    .where(users[:publications].not_eq(counts[:num]))
    .update_all(users[:publications].eq(counts[:num]))

这类操作的专业术语是JOIN子查询更新,以后搜索相关方案可以用这个关键词。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 11:04:55