Rails Rails 4 中,如何对 Active Record 两个结果集取并集?

daemon · 2016年10月10日 · 最后由 martin91 回复于 2016年10月11日 · 3344 次阅读

Rails4 中,如何对 Active Record 两个结果集取并集?

假设你的 model 是User

data_set1 = xxx.users
data_set2 = yyy.users
User.from("(#{data_set1.to_sql} UNION ALL #{data_set2.to_sql}) as users")

(data_set1 + data_set2).uniq

#1 楼 @piecehealth 感谢,用的你这种方法解决的。

#2 楼 @huacnlee 感谢,我的是 or 的合并,我的是 rails4.2,没有 or 这个方法,用了 where_or 这个 gem,但我的查询比较复杂,解决不了,最后用的@piecehealth 方案。

#3 楼 @Stone 感谢,想通过 sql 语句解决,不想把结果集取完后拼接。

#6 楼 @daemon 这种方法在数据量大的时候可能出现性能问题,所以合理创建索引

#6 楼 @daemon 用 Arel table 可以做到

users = User.arel_table
User.where(users[:foreign_field_id].in([1, 2, 3]).or(users[:foreign_field2_id].in([1,2,3]))).to_sql
# => "SELECT `users`.* FROM `users` WHERE (`users`.`foreign_field_id` IN (1, 2, 3) OR `users`.`foreign_field2_id` IN (1, 2, 3))"

OR的场景仅限于两个结果集都来自同样的超集,比如同一张表,或者同一个通过JOIN获得的结果集,这种情况其实就不是取并集了。 如果两个结果集来自不同的超集,这种情况才叫取并集,要用UNION ALL

比如想得到对一本书或一部电影感兴趣的人,可以book.fans UNION ALL film.fans,用OR实现的话就困难一些了

#8 楼 @martin91 我的场景跟@piecehealth 表述的第二种情况相似,结果集来自不同的超集,所以最后没选择用 or

#10 楼 @daemon 那就不是 or 的问题了,or 是同表,表示的是多种条件的组合。

需要 登录 后方可回复, 如果你还没有账号请 注册新账号