Rails/SQL:如何用JOIN查询无高级订阅的用户?
用JOIN方式查找无高级订阅的用户
针对你的User和Subscription模型关联,确实可以用LEFT JOIN实现需求,在不少数据库场景下比子查询性能更优,尤其是订阅数据量大的时候。下面是具体实现方法:
1. LEFT JOIN + 筛选无匹配记录
这是最经典的JOIN写法,通过左连接用户与他们的高级订阅,筛选出没有匹配到高级订阅的用户:
Rails ActiveRecord 写法
User.left_joins(:subscriptions) .where(subscriptions: { premium: true }) .where(subscriptions: { id: nil })
或者用SQL字符串更直观地控制条件:
User.left_joins(:subscriptions) .where("subscriptions.premium = ?", true) .where(subscriptions: { id: nil })
对应的原生SQL
SELECT users.* FROM users LEFT JOIN subscriptions ON users.id = subscriptions.user_id AND subscriptions.premium = true WHERE subscriptions.id IS NULL;
2. 结合GROUP BY的写法
如果需要同时统计用户订阅情况,也可以用分组后判断高级订阅数量为0:
User.left_joins(:subscriptions) .group(:id) .having("COUNT(CASE WHEN subscriptions.premium = true THEN 1 END) = 0")
和子查询的对比
- 多数主流数据库(PostgreSQL、MySQL)对LEFT JOIN的执行计划优化更成熟,能更好利用
subscriptions(user_id, premium)这类联合索引 - 逻辑上和你原有的子查询完全等价,都会包含没有任何订阅的用户
内容的提问来源于stack exchange,提问作者Crazy Cat
相关产品推荐
相关产品推荐

