获取 ActiveRecord 中的 Union 所有结果

Noo*_*bie 7 union activerecord ruby-on-rails arel ruby-on-rails-4

Rails 中如何获取 UNION 运算结果?

鉴于我有以下 SQL 语句

SELECT  "sip_trunks".* FROM "sip_trunks" WHERE "sip_trunks"."default" = t LIMIT 1 UNION ALL SELECT  "sip_trunks".* FROM "sip_trunks" WHERE "sip_trunks"."default" = f LIMIT 1 
Run Code Online (Sandbox Code Playgroud)

到目前为止,我已经成功地使用 AREL 和 union all 语句构建了 SQL。

SipTrunk.where(default: true).limit(1).union(:all,SipTrunk.where(default: false).limit(1))

Run Code Online (Sandbox Code Playgroud)

但尝试查询此结果和 AREL 即Arel::Nodes::UnionAll,我无法获得数据库结果。

同样to_sql在语句上运行会产生这样的 SQL..

( SELECT  "sip_trunks".* FROM "sip_trunks" WHERE "sip_trunks"."default" = $1 LIMIT 1 UNION ALL SELECT  "sip_trunks".* FROM "sip_trunks" WHERE "sip_trunks"."default" = $2 LIMIT 1 )
Run Code Online (Sandbox Code Playgroud)

这看起来像是一个准备好的语句,但我在数据库中没有看到任何准备好的语句

尝试使用上面的 SQLfind_by_sql

SipTrunk.find_by_sql(SipTrunk.where(default: true).limit(1).union(:all,SipTrunk.where(default: false).limit(1)).to_sql,[['default',true],['default',false]])
Run Code Online (Sandbox Code Playgroud)

出现以下错误

ActiveRecord::StatementInvalid: PG::SyntaxError: ERROR:  syntax error at or near "UNION"
LINE 1: ...trunks" WHERE "sip_trunks"."default" = $1 LIMIT 1 UNION ALL ...
Run Code Online (Sandbox Code Playgroud)

如何从这里获取最终的 SQL 行?

eng*_*nky 11

以下是我执行此操作的方法。

sql1 = SipTrunk.where(default: true).limit(1).arel
sql2 = SipTrunk.where(default: false).limit(1).arel
subquery = Arel::Nodes::As.new(
 Arel::Nodes::UnionAll.new(sql1,sql2),
 SipTrunk.arel_table
) 
SipTrunk.from(subquery)
Run Code Online (Sandbox Code Playgroud)

这将导致以下 SQL

SELECT 
  sip_trunks.*
FROM 
  ( SELECT 
      sip_trunks.* 
    FROM 
      sip_trunks
    WHERE 
      sip_trunks.default = t
    LIMIT 1
    UNION ALL 
    SELECT 
      sip_trunks.* 
    FROM 
      sip_trunks
    WHERE 
      sip_trunks.default = f
    LIMIT 1) AS sip_trunks
Run Code Online (Sandbox Code Playgroud)

这将返回一个ActiveRecord::Relation对象SipTrunk