使用Sequel我想将两个子查询连接在一起,共享一些列名,然后在select中对这些列进行表格限定。
如果两个数据集只是表格,我理解如何做到这一点。例如。如果我有users
表和items
表,其中包含属于用户的项目,并且我想列出项目的名称及其所有者的名称:
@db[:items].join(:users, :id => :user_id).
select{[items__name, users__name.as(user_name)]}
产生
SELECT "items"."name", "users"."name" AS "user_name"
FROM "items"
INNER JOIN "users" ON ("users"."id" = "items"."user_id")
根据需要。
但是,如果我加入两个代表子查询的任意数据集(称为my_items
和my_users
),我不确定如何做到这一点
语法可能采用
形式my_items.join(my_users, :id => :user_id).
select{[ ... , ... ]}
我将提供合格的列名来访问my_users.name
和my_items.name
。这样做的恰当语法是什么?
部分解决方案是使用t1__name
作为第一个参数,因为提供给连接的数据集似乎与t1
,t2
等等别名。但是这并不是'帮我限定项目名称,我需要提供给第二个参数。
我认为最理想的解决方案可以让我为联接中的数据集提供别名,例如喜欢以下内容(当然,由于多种原因,这不起作用)
my_items.as(alias1).join(my_users.as(alias2), :id => :user_id).
select{[alias1__name, alias2__name ]}
有没有办法做到这一点?
谢谢!
更新
我认为from_self
让我成为那里的一部分,例如。
my_items.from_self(:alias => :alias1).join(my_users, :id => :user_id).
select{[alias1__name, t1__name]}
似乎做对了。
答案 0 :(得分:7)
好的,感谢罗纳德霍尔斯豪森的暗示,得到了它。关键是在第一个数据集上使用.from_self
,并在联接中提供:table_alias
选项:
my_items.from_self(:alias => :alias1).
join(my_users, {:id => :user_id}, :table_alias => :alias2).
select(:alias1__name, :alias2__name)
产生SQL
SELECT "alias1"."name", "alias2"."name"
FROM ( <my_items dataset> ) AS "alias1"
INNER JOIN ( <my_users dataset> ) AS "alias2"
ON ("alias2"."id" = "alias1"."user_id")
请注意,连接哈希(join
的第二个参数)需要使用显式花括号来区分包含:table_alias
的选项哈希。
答案 1 :(得分:2)
我找到的唯一方法是在数据库上使用from
方法,在:table_alias
方法上使用join
,但这些方法不适用于模型,所以我不得不使用模型类中的table_name
。即,
1.9.3p125 :018 > @db.from(Dw::Models::Contract.table_name => 'C1')
=> #<Sequel::SQLite::Dataset: "SELECT * FROM `vDimContract` AS 'C1'">
1.9.3p125 :019 > @db.from(Dw::Models::Contract.table_name => 'C1').join(Dw::Models::Contract.table_name, {:c1__id => :c2__id}, :table_alias => 'C2')
=> #<Sequel::SQLite::Dataset: "SELECT * FROM `vDimContract` AS 'C1' INNER JOIN `vDimContract` AS 'C2' ON (`C1`.`Id` = `C2`.`Id`)">
1.9.3p125 :020 > @db.from(Dw::Models::Contract.table_name => 'C1').join(Dw::Models::Product.table_name, {:product_id => :c1__product_id}, :table_alias => 'P1')
=> #<Sequel::SQLite::Dataset: "SELECT * FROM `vDimContract` AS 'C1' INNER JOIN `vDimProduct` AS 'P1' ON (`P1`.`ProductId` = `C1`.`ProductId`)">
我唯一不喜欢from_self
的是它使用子查询:
1.9.3p125 :021 > Dw::Models::Contract.from_self(:alias => 'C1')
=> #<Sequel::SQLite::Dataset: "SELECT * FROM (SELECT * FROM `vDimContract`) AS 'C1'">