8

使用Sequel我想将两个共享一些列名的子查询连接在一起,然后在选择中对这些列进行表限定。

如果两个数据集只是表,我了解如何执行此操作。例如,如果我有一个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_itemsmy_users) ,我不确定如何执行此操作

语法可能采用以下形式

my_items.join(my_users, :id => :user_id).
  select{[ ... , ... ]}

我将提供合格的列名来访问my_users.namemy_items.name. 执行此操作的适当语法是什么?

部分解决方案是t1__name用于第一个参数,因为提供给连接的数据集似乎使用 , 等别名t1t2但这并不能帮助我限定项目名称,我需要提供给第二个参数。

我认为最理想的解决方案将使我能够为连接中的数据集提供别名,例如如下所示(当然,由于多种原因这不起作用)

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]}

似乎做正确的事。

4

2 回答 2

9

好的,多亏了 Ronald Holshausen 的提示,明白了。关键是.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

于 2013-01-12T10:06:39.987 回答
2

我发现的唯一方法是使用fromDB 上的方法和方法:table_alias上的join方法,但这些方法不适用于模型,所以我不得不使用table_name模型类中的方法。IE,

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'"> 
于 2013-01-11T04:20:07.607 回答