8

Sequelを使用して、いくつかの列名を共有する2つのサブクエリを結合し、selectでそれらの列をテーブル修飾します。

2つのデータセットが単なるテーブルである場合、これを行う方法を理解しています。たとえば、ユーザーに属するアイテム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ただし、サブクエリを表す2つの任意のデータセットを結合している場合(これらをとと呼ぶmy_users) 、これを行う方法がわかりません。

構文はおそらく次の形式を取ります

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

アクセスするための修飾された列名を指定しmy_users.nameますmy_items.name。これを行うための適切な構文は何ですか?

部分的な解決策は、結合に提供されるデータセットが、などでエイリアス化されているように見えるため、最初の引数に使用することt1__nameです。しかし、それは、2番目の引数に提供する必要があるアイテム名を修飾するのに役立ちません。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

OK、ロナルド・ホルスハウゼンのヒントのおかげで、それを手に入れました。重要なのは.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")

結合ハッシュ(の2番目の引数join)は、を含むオプションハッシュと区別するために、明示的な中括弧が必要であることに注意してください:table_alias

于 2013-01-12T10:06:39.987 に答える
2

私が見つけた唯一のfrom方法は、DBとメソッドでメソッド: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'"> 
于 2013-01-11T04:20:07.607 に答える