用 arel 中的 union 重写复杂的查询?
我有以下模型
class Courier < ActiveRecord::Base
has_many :coverages
end
class Coverage < ActiveRecord::Base
belongs_to :courier
belongs_to :country_code
end
class CountryCode < ActiveRecord::Base
end
,然后有以下查询:
# could i translate this into cleaner arel?
result = Courier.find_by_sql(<<SQL
select * from
(
select cc.*, cv.rate from couriers cc, coverages cv
where cv.country_code_id=#{country.id} and cv.courier_id=cc.id
union
select cc.*, cv.rate from couriers cc, coverages cv
where cv.country_code_id is null
and cv.courier_id=cc.id
and cv.courier_id not in (select courier_id from coverages where country_code_id=#{country.id})
) as foo order by rate asc
SQL
)
简而言之:我正在寻找具有给定国家/地区代码覆盖范围或具有空国家/地区代码覆盖范围的所有快递公司(后备)。
该查询有效,但我想知道是否有更好的方法来编写它?
I have the following models
class Courier < ActiveRecord::Base
has_many :coverages
end
class Coverage < ActiveRecord::Base
belongs_to :courier
belongs_to :country_code
end
class CountryCode < ActiveRecord::Base
end
and then i have the following query:
# could i translate this into cleaner arel?
result = Courier.find_by_sql(<<SQL
select * from
(
select cc.*, cv.rate from couriers cc, coverages cv
where cv.country_code_id=#{country.id} and cv.courier_id=cc.id
union
select cc.*, cv.rate from couriers cc, coverages cv
where cv.country_code_id is null
and cv.courier_id=cc.id
and cv.courier_id not in (select courier_id from coverages where country_code_id=#{country.id})
) as foo order by rate asc
SQL
)
In short: i am looking for all couriers that have a coverage for the given country-code or a coverage with an empty country-code instead (the fallback).
The query works, but i am wondering if there are any better ways to write it?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
如果您想保留 find_by_sql,您可以将查询压缩为:
If you wanted to keep the
find_by_sql
you could condense the query into:使用 arel,获得类似的东西似乎并不困难:
这将执行一个查询,获取给定条件的覆盖范围和关联的快递公司。我不认为为了获得预期的结果而调整这一点会很困难。
With arel it seems not very difficult to get something similar:
This will perform one query that gets the coverages and associated couriers for the given conditions. I do not believe it would be very difficult to adapt this in order to get the intended result.