graphがあったぜSequel
Sequelのjoinの戻り値がどう…というエントリを書いてうだうだ言っていたが、graphというメソッドを使えば一件落着?
[pyg language=“ruby”] #! /usr/bin/ruby
require ‘sequel’ require ‘pp’
DB=Sequel.sqlite
DB.create_table :tbl1s do primary_key :id String :value end
DB.create_table :tbl2s do primary_key :id String :value2 Integer :tbl1_id end
class Tbl1 < Sequel::Model ; end class Tbl2 < Sequel::Model ; end
if $0==__FILE__ Tbl1.insert(:value=>“tbl1data1”) # tbl1s.id=>1 Tbl1.insert(:value=>“tbl1data2”) # tbl1s.id=>2 Tbl2.insert(:value2=>“tbl2data1”, :tbl1_id=>2) # tbl2s.id=>1 Tbl2.insert(:value2=>“tbl2data2”, :tbl1_id=>1) # tbl2s.id=>2
SELECT * FROM tbl1s INNER JOIN tbl2s ON (tbl2s.tbl1_id = tbl1s.id)
t1=Tbl1.join(Tbl2, :tbl1_id=>:id).first pp t1 # Tbl1{:id=>1, :value=>“tbl1data2”, :value2=>“tbl2data1”, :tbl1_id=>2} t2=Tbl1.graph(Tbl2, :tbl1_id=>:id).first pp t2 # Tbl1{:id=>1, :value=>“tbl1data1”, :tbl2s_id=>2, :value2=>“tbl2data2”, :tbl1_id=>1} end [/pyg]
重複するカラム名はTbl1側が普通に使われ、Tbl2側のカラム名は「テーブル名_カラム名」になる。重複しなければそのまま使える。モデルのクラスはTbl1側。joinがこの仕様だったら良かったんだ。
しかしSQL文を見ると、graphメソッドはLEFT OUTER JOINですね。joinメソッドはINNTER JOINですから、当然結果は異なるわけで、joinは両方にデータがなければ出てこず、graphはTbl1にデータがあれば出てくる。
[pyg language=“ruby”] Tbl1.insert(:value=>“tbl1data3”) # tbl1s.id=>3 Tbl1.join(Tbl2, :tbl1_id=>:id).count # 2(INNNER JOIN) Tbl1.graph(TBl2, :tbl1_id=>:id).count # 3(LEFT OUTER JOIN) Tbl1.left_outer_join(Tbl2, :tbl1_id=>:id).count # 3(LEFT OUTER JOIN) [/pyg]
これまでの結論:やっぱSequelのjoin()の仕様はおかしい。