在 Ruby on Rails 4 中使用 Active Record 或 Squeel Gem 重写 SQL 查询

Posted

技术标签:

【中文标题】在 Ruby on Rails 4 中使用 Active Record 或 Squeel Gem 重写 SQL 查询【英文标题】:Re-writing a SQL Query using Active Record or the Squeel Gem in Ruby on Rails 4 【发布时间】:2014-02-02 07:48:17 【问题描述】:

我在使用 Ruby on Rails 4 在 Squeel 或直接 Active Record 中重写此 SQL 查询时遇到很多问题。

查询中的所有 3 个数字都需要在执行前传递给查询。 SQL 查询如下。

SELECT "users".* 
FROM "users"  
WHERE "users"."id" 
IN (SELECT "users"."id" FROM "users"  
INNER JOIN marketing_assets ON users.id = marketing_assets.user_id 
WHERE  marketing_assets.marketing_platform_id= 3 
GROUP BY users.id HAVING COUNT(DISTINCT marketing_assets.marketing_platform_id) = 1)

你可以在Error when trying to chain class method in controller in Ruby on Rails找到更多关于它是如何使用的细节

【问题讨论】:

【参考方案1】:
marketing_assets_id = 3
limit_marketing_assets = 1
User.joins(:marketing_assets).where(:marketing_assets => :marketing_platform_id => marketing_assets_id).group(:users => :id).having("COUNT(DISTINCT marketing_assets.marketing_platform_id) = #limit_marketing_assets")

【讨论】:

感谢@AhmadHussain,where 子句值中的 marketing_platform_id 是一个变量,也可以是 2 个或更多值。此外,“COUNT(DISTINCT marketing_assets.marketing_platform_id) = 1”中的值“1”也是可变的,具体取决于 where 子句中有多少值。这将如何重写?此外,使用 Squeel 更容易吗? Squeel 很好,但总是使用一些 gem 来执行任务并不是一个好习惯,因为在这种情况下,这项工作可以在没有 squeel 的情况下完成,这就是我没有使用它的原因。【参考方案2】:

这是我最终使用 Squeel 编写的查询。它对我有用。

User.whereusers.id.in(User.joinsmarketing_assets
.where((['marketing_assets.marketing_platform_id = ?' ] * platforms.count)
.join(' OR '), *platforms).groupusers.id
.havingmarketing_assets => 
COUNT(DISTINCT(marketing_assets.marketing_platform_id)) => platforms.count )

【讨论】:

以上是关于在 Ruby on Rails 4 中使用 Active Record 或 Squeel Gem 重写 SQL 查询的主要内容,如果未能解决你的问题,请参考以下文章

在 ruby​​ on rails 5.2.4 中使用谷歌云翻译时出错

在 Ruby on Rails 4.2 中使用 Cocoon gem 嵌套表单

Ruby on Rails 4,在视图中形成

在 Ruby on Rails 3.2.14 / Ruby 2.0.0 / PostgreSQL 9.2.4 中使用 activerecord 从序列中检索 nextval

如何在 ruby​​ on rails 4 中创建高级搜索

ruby on rails - 问题捆绑安装nokogiri 1.7.2 on ruby on rails 4.x.