Ruby on rails ActiveRecord查询以查找过去3个月内未进行购买的所有用户
我有一个具有关联购物车的用户模型。每个购物车都有一个“在日期时购买”列。 我想选择过去3个月内没有购买购物车的所有用户 我想一个简单的例子:Ruby on rails ActiveRecord查询以查找过去3个月内未进行购买的所有用户,ruby-on-rails,ruby-on-rails-3,activerecord,arel,Ruby On Rails,Ruby On Rails 3,Activerecord,Arel,我有一个具有关联购物车的用户模型。每个购物车都有一个“在日期时购买”列。 我想选择过去3个月内没有购买购物车的所有用户 我想一个简单的例子: User.joins(:carts).where('not carts.purchased_at < ?', 3.months.ago) 这会起作用,但事实似乎并非如此。我被退回过去3个月内购买过东西的用户记录 有什么想法吗?我建议您使用原始SQL User.find_by_sql(' SELECT users.* FROM users WHE
User.joins(:carts).where('not carts.purchased_at < ?', 3.months.ago)
这会起作用,但事实似乎并非如此。我被退回过去3个月内购买过东西的用户记录
有什么想法吗?我建议您使用原始SQL
User.find_by_sql('
SELECT users.* FROM users WHERE id NOT IN
(SELECT users.id FROM users LEFT JOIN carts ON users.id = carts.user_id
WHERE carts.purchased_at < ?)
', 3.months.ago)
记住,这只是一个建议。我认为代码需要一些重构,但你已经想到了。我建议你使用原始SQL
User.find_by_sql('
SELECT users.* FROM users WHERE id NOT IN
(SELECT users.id FROM users LEFT JOIN carts ON users.id = carts.user_id
WHERE carts.purchased_at < ?)
', 3.months.ago)
记住,这只是一个建议。我认为代码需要一些重构,但你已经有了主意。使用gem进行如此复杂的查询:
User.where{id.not_in User.joins{carts}.where{carts.purchased_at > 3.months.ago}}
使用gem进行此类复杂查询:
User.where{id.not_in User.joins{carts}.where{carts.purchased_at > 3.months.ago}}
如果您正在使用AR3和ARel:
User.joins(:carts).where(Cart.arel_table[:purchased_at].gt(3.months.ago))
如果您正在使用AR3和ARel:
User.joins(:carts).where(Cart.arel_table[:purchased_at].gt(3.months.ago))
您应该能够在普通活动记录中执行此操作:
User.joins(:carts)
.group("users.id")
.having("MAX(carts.purchased_at) < ?", 3.months.ago)
您应该能够在普通活动记录中执行此操作:
User.joins(:carts)
.group("users.id")
.having("MAX(carts.purchased_at) < ?", 3.months.ago)
如果你有一个巨大的购物车,使用MAX和GroupBy可能会很慢。我会使用这种方法
nq = Cart.where("carts.user_id = users.id AND carts.purchased_at >= ?", 3.months.ago)
User.where("NOT EXISTS (#{nq.to_sql})")
更好的是,我会在用户模型中添加一个名为last_purchase_at的列,以提高查询效率
class User
# add a new column called last_purchase_at
# index the last_purchase_at column
def self.dormant_users(period=3.months)
User.where("last_purchase_at <= ?", period.ago)
end
end
将此代码添加到迁移脚本中,以设置现有用户模型的“最后一次购买”列
现在,您可以按如下方式获取休眠用户:
User.dormant_users # dormant for last 6 months
User.dormant_users(6.months) # dormant for last 6 months
如果你有一个巨大的购物车,使用MAX和GroupBy可能会很慢。我会使用这种方法
nq = Cart.where("carts.user_id = users.id AND carts.purchased_at >= ?", 3.months.ago)
User.where("NOT EXISTS (#{nq.to_sql})")
更好的是,我会在用户模型中添加一个名为last_purchase_at的列,以提高查询效率
class User
# add a new column called last_purchase_at
# index the last_purchase_at column
def self.dormant_users(period=3.months)
User.where("last_purchase_at <= ?", period.ago)
end
end
将此代码添加到迁移脚本中,以设置现有用户模型的“最后一次购买”列
现在,您可以按如下方式获取休眠用户:
User.dormant_users # dormant for last 6 months
User.dormant_users(6.months) # dormant for last 6 months
这只是检索所有在3个月前购买过产品的用户,而不管他们是否在过去3个月内购买过产品。我只想看到在过去3个月内没有购买的用户。这只是检索所有在3个月前购买的用户,不管他们在过去3个月内是否购买。我只想看到在过去3个月内没有购买过产品的用户。active record似乎是一个不错的dsl,但安装此gem以满足这一单一情况可能有点过分。@KJF您可以查看其他查询,也许您会找到更多地方使用squel以避免SQL文本片段。顺便说一句,您不认为您必须使用>签名,而不是在active record周围安装一个很好的dsl,但是安装这个gem来满足这一单一情况可能有点过头了。@KJF您可以看看您的其他查询,也许您会找到更多的地方使用squel来避免SQL文本片段。顺便说一句,你不认为你必须要有>符号,而不是我一直在寻找的。谢谢你能解释一下group方法中User.column_names.map的原因吗?如果我用“users.id”组来代替它,效果也一样。你说得对。在控制台中测试时,我遇到了一些奇怪的问题。但这确实有效。谢谢你的更正!这就是我要找的。谢谢你能解释一下group方法中User.column_names.map的原因吗?如果我用“users.id”组来代替它,效果也一样。你说得对。在控制台中测试时,我遇到了一些奇怪的问题。但这确实有效。谢谢你的更正!