我正在使用RAILS 4和MySQL 服務通過服務場所有很多地方。我是否在AREL查詢中使用別名引用子查詢?
我想創建一個AREL相當於下面的SQL查詢:
SELECT DISTINCT
services . *
FROM
services
INNER JOIN
(SELECT DISTINCT
`services` . *
FROM
`services`
LEFT OUTER JOIN `service_places` ON `service_places`.`service_id` = `services`.`id`
WHERE
`service_places`.`place_id` IN (SELECT DISTINCT
`places`.`id`
FROM
`places`
WHERE
(`places`.`place_name` LIKE '%war%'))) s1 ON s1.id = services.id
INNER JOIN
(SELECT DISTINCT
`services` . *
FROM
`services`
LEFT OUTER JOIN `service_places` ON `service_places`.`service_id` = `services`.`id`
WHERE
`service_places`.`place_id` IN (SELECT DISTINCT
`places`.`id`
FROM
`places`
WHERE
(`places`.`place_name` LIKE '%leam%'))) s2 ON s2.id = services.id;
理想的情況下,這將通過insersect查詢來完成,但已經做了一些閱讀中,我發現,雖然AREL提供了一個交叉,MySQL的不支持它。所以我使用連接創建了SQL,它返回了我期望的數據。
我已經得到了一些AREL代碼來創建兩個子查詢和工作正常:
s = Service.arel_table
sp = ServicePlace.arel_table
p = Place.arel_table
search_from = "leam"
search_to = "war"
############
# From QUERY
############
from_subquery = Place.select(p[:id]).where(p[:place_name].matches("%#{search_from}%")).uniq
from_query = Service.joins(
s.join(sp, Arel::Nodes::OuterJoin).on(sp[:service_id].eq(s[:id]))
.join_sql
).uniq
from_query = from_query.where(sp[:place_id].in(from_subquery.ast))
##########
# To Query
##########
to_subquery = Place.select(p[:id]).where(p[:place_name].matches("%#{search_to}%")).uniq
to_query = Service.joins(
s.join(sp, Arel::Nodes::OuterJoin).on(sp[:service_id].eq(s[:id]))
.join_sql
).uniq
to_query = to_query.where(sp[:place_id].in(to_subquery.ast))
我的問題進來試圖創建AREL查詢具有以下兩個子查詢。我試過,但它失敗:
query = Service.joins(from_subquery.as('s1')).on(s1[:id].eq(s[:id]))
.join(to_subquery.as('s2')).on(s2[:id].eq(s[:place_id]))
.join_sql
).uniq
NameError: undefined local variable or method `s1' for main:Object
我很高興,我建這個方法是可以的,因爲我有一個類似的語法查詢的運行和工作沒有問題(見下文):
query = Service.joins(
s.join(sp, Arel::Nodes::OuterJoin).on(sp[:service_id].eq(s[:id]))
.join(p, Arel::Nodes::OuterJoin).on(p[:id].eq(sp[:place_id]))
.join_sql
).uniq
我知道問題在於我如何引用關係中的子查詢,但不知道這是什麼。我已經看到了「create_table_alias」,「別名」和「as」方法的引用,但找不到任何幫助我的例子。這可能是非常明顯的事情,因爲我總是看不到它。
如果有人能幫助,我將不勝感激。
在此先感謝。
UPDATE 01:
我發現一個AREL語法創建人http://www.scuttle.io/,可以是用於生成AREL語法是有用的。它並不適用於我的整體,但對於它的小塊。您需要將「喜歡」更改爲「=」,因爲它不包含它們。不過,您可以將「eq」更改回「匹配」。
UPDATE 02:使用CTE與該代碼創建的阿雷爾:: SelectManager對象
試過。但是,進一步的研究表明你不能在MYSQL中使用CTE。下面顯示了我使用的代碼作爲參考。
cte_table = Arel::Table.new(:cte_table)
composed_cte = Arel::Nodes::As.new(cte_table, from_query)
s.join(cte_table).on(s[:id].eq(cte_table[:id])).project(s[Arel.star]).with(composed_cte)
非常感謝,下週我見到你時必須讓你品嚐一杯。 – 2014-12-12 16:47:07