[Seasar-user:16114] Re: [S2JDBC] innerJoin と leftOuterJoin で同じ Entity を指定したい

Koichi Kobayashi [E-MAIL ADDRESS DELETED]
2008年 10月 26日 (日) 18:00:17 JST


小林 (koichik) です.

Date:    Sun, 26 Oct 2008 06:27:36 +0900
From:    Shotaro Tsubouchi <[E-MAIL ADDRESS DELETED]>
To:      [E-MAIL ADDRESS DELETED]
Subject: [Seasar-user:16112] Re: [S2JDBC] innerJoin と leftOuterJoin で同じ Entity を指定したい

> select T1_.*, T3_.*
>   from FOO T1_
>  inner join BAA T2_ on T2_.FOO_ID = T1_.ID and T2_.ID = 1
>  inner join BAA T3_ on T3_.FOO_ID = T1_.ID
> 
> こう書く方が自然なのではないでしょうか。

EXISTS を使わないで結合するならその条件は ON で
書くべきですが,自分が [Seasar-user:16110] で
それは選択条件だと書いたのはそういう意味ではなく,

select T1_.*, T2_.*
from FOO T1_
 inner join BAA T2_ on T2_.FOO_ID = T1_.ID
where
 exists (select * from BAA FOO_ID = T1_.ID and ID = 1)

ということです.
SQL としてはどちらも等価ですが,意図が明瞭なのは
こちらだと思います.
あるいは,

select T1_.*, T2_.*
from (
  select * from FOO F
  where
    exists (select * from BAA FOO_ID = F.ID and ID = 1)
  ) T1_
  inner join BAA T2_ on T2_.FOO_ID = T1_.ID

とか.
これはもちろん AutoSelect では表現できませんが.

> select() // jdbcManager.from(Foo.class)
>     .innerJoin(baaList(), false, eq(baaList().id(), 1))
>     .innerJoin(baaList())
>     .getResultList();
> 
> で済んで、フェッチしない結合の重複を許すだけで良いですし。

この例は結合さえできれば後は用がないので
それで済みますが,結合できた後に他の結合も
含めた選択条件が必要になると無理が出てきます.

まぁ,AutoSelect で扱える範囲を少し広げるだけと
割り切れば,フェッチしない結合は重複を許し,
WHERE では使えないとするのは悪くないのですが,
現在はフェッチしない結合を WHERE で扱えているので,
無条件に WHERE で使えなくすると既存のコードが
動かなくなり,重複した時だけ使えなくすると
いかにも落とし穴になりそうです.

> なにげに、結合条件の追加の例自体、そういう使われ方だったりしてますw

違いますよ.この例は本当に結合の条件です.
サラリーが 1000 より多い従業員だけを結合するので,
WHERE より JOIN ON で書く方が適切です.

なんとなく,JOIN ON には外部キーだけ指定すべきと
主張したと誤解されてそうですが,そんなつもりは
ありません.

ID = 1 の部分だけを選択条件と書いたのではなく,
その結合全体が選択条件だと書いたのです.


-- 
<component name="koichik">
    <property name="fullName">"Koichi Kobayashi"</property>
    <property name="email">"[E-MAIL ADDRESS DELETED]"</property>
    <property name="blog">"http://d.hatena.ne.jp/koichik"</property>
</component>



Seasar-user メーリングリストの案内