sql - 按模型关联计数排序

标签 sql ruby-on-rails ruby activerecord globalization

我有一个模型事件,它依赖于执行,而执行又依赖于具有 ProductTranslation 的产品。 同样的事件模型有很多订单。 我想在表格中显示事件并能够按计数(订单)对它们进行排序,按名称搜索... 我发出了sql请求

select e.id, pt.name, nbc.nb
from `events` as e
inner join `executions` as ex on e.`execution_id` = ex.`id`
inner join `products` as p on ex.`product_id` = p.`id`
left outer join (select product_id, `name` from `product_translations` where `locale` ='en' group by `product_id`  ) as pt on pt.`product_id` = p.id
left outer join (select event_id, COUNT(*) as nb from orders group by event_id) as nbc on nbc.event_id = e.id
where pt.name like '%plane%'
order by 3 desc

但我不能用 ActiveReccord 转录它,特别是 order by count(orders)

顺便说一下,我使用 gem globalize 进行翻译。

最佳答案

一种将 SQL 查询转换为 Rails 的方法:

初始请求

select e.id, pt.name, nbc.nb
from `events` as e
inner join `executions` as ex on e.`execution_id` = ex.`id`
inner join `products` as p on ex.`product_id` = p.`id`
left outer join (select product_id, `name` from `product_translations` where `locale` ='en' group by `product_id`  ) as pt on pt.`product_id` = p.id
left outer join (select event_id, COUNT(*) as nb from orders group by event_id) as nbc on nbc.event_id = e.id
where pt.name like '%plane%'
order by 3 desc

第一步 确定主表;在这里,它是 Event。所以这是来自您的 Event 模型的调用。

Event
  .select("events.id, pt.name, nbc.nb")
  .joins("inner join `executions` as ex on events.`execution_id` = ex.`id`
          inner join `products` as p on ex.`product_id` = p.`id`
          left outer join (select product_id, `name` from `product_translations` where `locale` ='en' group by `product_id`  ) as pt on pt.`product_id` = p.id
          left outer join (select event_id, COUNT(*) as nb from orders group by event_id) as nbc on nbc.event_id = events.id")
  .where("pt.name like '%plane%'")
  .order("3 desc")

第二步 将inner join转化为关系。您必须声明 has_many/belongs_toExecutionProduct

Model Event < AR::Base
  has_many :executions
  has_many :products, :through => :executions

Event
  .select("events.id, pt.name, nbc.nb")
  .joins(:products)
  .joins("left outer join (select product_id, `name` from `product_translations` where `locale` ='en' group by `product_id`) as pt on pt.`product_id` = products.id
          left outer join (select event_id, COUNT(*) as nb from orders group by event_id) as nbc on nbc.event_id = events.id")
  .where("pt.name like '%plane%'")
  .order("3 desc")

子查询出来 目前左外连接不能用 Rails 4 完成,但是你可以提取你的子查询。

sub_query1 = ProductTranslation
               .select("product_id, `name`")
               .where("`locale` ='en'")
               .group("`product_id`")

sub_query2 = Order
               .select("event_id, COUNT(*) as nb")
               .group("event_id")

Event
  .select("events.id, pt.name, nbc.nb")
  .joins(:products)
  .joins("left outer join (#{sub_query1.to_sql}) as pt on pt.`product_id` = products.id
          left outer join (#{sub_query2.to_sql}) as nbc on nbc.event_id = events.id")
  .where("pt.name like '%plane%'")
  .order("3 desc")

其他一些更正 SQL 命令是大写的,条件是散列,更喜欢对表模型使用 table_name。

sub_query1 = ProductTranslation
               .select("`product_id`, `name`")
               .where({ :locale => 'en' })
               .group(:product_id)

sub_query2 = Order
               .select("event_id, COUNT(*) as nb")
               .group("event_id")

Event
  .select("#{Event.table_name}.id, pt.name, nbc.nb")
  .joins(:products)
  .joins("LEFT OUTER JOIN (#{sub_query1.to_sql}) AS pt
            ON pt.`product_id` = #{Product.table_name}.id
          LEFT OUTER JOIN (#{sub_query2.to_sql}) AS nbc
            ON nbc.event_id = #{Event.table_name}.id")
  .where("pt.name LIKE ?", '%plane%')
  .order("3 DESC")

瞧!

关于sql - 按模型关联计数排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29844463/

相关文章:

ruby - 西纳特拉:三个日志

ruby - 如何配置 Ruby 以在 Windows 上为 Sench-touch 使用 compass

ruby - Ruby 中的静态变量生成 "one up counter function"?

sql - MySQL:指定我希望返回的行的顺序

sql - 自定义 ORDER BY 忽略 'the'

SQL查询将多行值归一化为一行一列字段

ruby-on-rails - 在控制台中测试路由

sql - 在 db2 中优化查询

javascript - 使用 Google Places Web API 的 Rails( key 不起作用)

ruby-on-rails - 找出在 Ruby/Rails 中定义方法的位置(相对于 Java)