InnerJoinについて

42 views
Skip to first unread message

志水正幸

unread,
Jun 17, 2019, 2:37:10 AM6/17/19
to DBFluteユーザの集い
志水です。
いつもお世話になっております。

買掛データ(T_KAIKAKE)と仕入先データ(M_SHIIRESAKI)を内部結合し
買掛データおよび仕入先データを取得したいと考えています。

下記のように設定しデータを取得したのですが
SetupSelectでInnerJoin()を行うと仕入先データの内容が取れてきません。
SetupSelect_MShiiresakiのouter joinの場合は仕入先データは取得できます。
InnerJoinの場合はInnerJoin側データは取得できないというのは仕様でしょうか?
ちなみに、両方設定すると仕入先データは取得はできます。


◆additionalForeignKeyMap
     # 買掛ヘッダと仕入先
    ; [FK_T_KAIKAKE_HEAD_M_SHIIRESAKI] = map:{
        ; localTableName = T_KAIKAKE_HEAD
        ; foreignTableName = M_SHIIRESAKI
        ; localColumnName = KIK_SRE_CODE
        ; foreignColumnName =  SRE_CODE
        ; fixedCondition = 
        SRE_KANA LIKE  /*TargetSreKana(String)*/null
    }


◆C#コード
                    TKaikakeHeadCB cbean = new TKaikakeHeadCB();
//cbean.SetupSelect_MShiiresaki(TxtSearchString.Text + @"%");
                    cbean.Query().SetKikCode_PrefixSearch(TxtSearchCode.Text);
                    cbean.Query().QueryMShiiresaki(TxtSearchString.Text + @"%").InnerJoin();
                    cbean.Query().AddOrderBy_KikCode_Asc();
                    SearchDataList = cmnDBLc.GetTKaikakeHeadList(cbean);

kubo

unread,
Jun 17, 2019, 2:55:57 AM6/17/19
to DBFluteユーザの集い
jfluteです

志水さん、こんにちは


もう少し状況を確認させてください。
以下のようなSQLを想定されているわけですよね?

from T_KAIKAKE_HEAD kai
inner join M_SHIIRESAKI shii -- ★ここが inner join だったり left outer join だったり
on kai.KIK_SRE_CODE = shii.SRE_CODE
and shii.SRE_KANA LIKE /*TargetSreKana(String)*/null -- ★ここが引数次第の検索に

そして以下のような挙動をするということでしょうか?

inner join の場合: M_SHIIRESAKI は検索されるけど対応する M_SHIIRESAKI が取得(get)できない
left outer join の場合: 対応する M_SHIIRESAKI のデータが正しく取得(get)できる

そして、どちらも、T_KAIKAKE_HEAD の件数は変わらないということでしょうか?


C#のコードで言うと...

inner joinの場合:
cbean.SetupSelect_MShiiresaki(TxtSearchString.Text + @"%");
に加えて、Query()...InnerJoin() も実行する

left outer join の場合:
cbean.SetupSelect_MShiiresaki(TxtSearchString.Text + @"%");
のみで、Query()...InnerJoin() はしない

このような条件でよろしいでしょうか?

> ちなみに、両方設定すると仕入先データは取得はできます。

また、こちらの「両方設定すると」がどのような実装のことを指すのがわかりませんでした。


いずれにせよ、以下が想定される挙動です。

inner join の場合の処理は...
1. M_SHIIRESAKI を SRE_KANA で絞り込んで
2. 存在するM_SHIIRESAKI だけの T_KAIKAKE_HEAD にする
 => T_KAIKAKE_HEADが存在すれば対応するM_SHIIRESAKIも必ず存在する
 => その代わりM_SHIIRESAKI が存在しないT_KAIKAKE_HEADも検索結果から消える

left outer join の場合の処理は...
1. M_SHIIRESAKI を SRE_KANA で絞り込んで
2. T_KAIKAKE_HEAD から見て存在する (絞り込まれた) M_SHIIRESAKI だけを付与する

志水正幸

unread,
Jun 17, 2019, 3:29:05 AM6/17/19
to DBFluteユーザの集い

jfluteさん
こんにちは。

お忙しいとこ、いつもすいません。


>inner joinの場合: 

>cbean.SetupSelect_MShiiresaki(TxtSearchString.Text + @"%"); 
>に加えて、Query()...InnerJoin() も実行する 
ああ~なるほど。
私の使い方が間違っていますね。
inner joinの場合「 cbean.Query().QueryMShiiresaki(TxtSearchString.Text + @"%").InnerJoin();」
しか実行していませんでした。
これ、InnerJoinの場合は両方必要なんですね(^ ^;
てっきり、InnerJoinの方だけでいいと思ってました。

>また、こちらの「両方設定すると」がどのような実装のことを指すのがわかりませんでした。 
これが、勘違いしていたためのソレでした(笑)
ありがとうございました。。


あと、別件の質問でもうしわけないですが
commonColumnMap.dfpropの追加日付、更新日付などの
共通カラムにセットするものがありますが
現案件はリプレース案件でDBが確定していまして
DBカラムにはそれぞれテーブル毎に「SRE_」「KIK_」などの
プリフィックスが以下のように付加されているのですが
 ⇒「SRE_LASTDATE」「SRE_ADDDATE」 「SRE_UPDDATE」 「SRE_UPDUSER」
この最初のプリフックスを無視してセットするようなことはできるのでしょうか?


以上、宜しくお願い致します。





2019年6月17日月曜日 15時55分57秒 UTC+9 jflute:

kubo

unread,
Jun 17, 2019, 5:11:23 AM6/17/19
to DBFluteユーザの集い
jfluteです

> inner joinの場合「 cbean.Query().QueryMShiiresaki(TxtSearchString.Text + @"%").InnerJoin();」
> しか実行していませんでした。

りょうかいです。
そうですね、SetupSelectは「select句に関連テーブルをセットアップする」になりますので、
joinの方式に関わらず関連テーブルのデータ取得するためには必要です。
(Query...InnnerJoinは、そのリレーションシップのjoin方式を変えるだけですね)

>  ⇒「SRE_LASTDATE」「SRE_ADDDATE」 「SRE_UPDDATE」 「SRE_UPDUSER」

うおお、なるほど、これって規則的でしょうか?
例えば「テーブル名 + _LASTDATE」とか、テーブル名じゃないにしても、
「このテーブル名だったら必ずprefixがこれになる」とか。

志水正幸

unread,
Jun 17, 2019, 10:53:28 AM6/17/19
to DBFluteユーザの集い

志水です。
お忙しいところありがとうございます。

>例えば「テーブル名 + _LASTDATE」とか、テーブル名じゃないにしても、 
>「このテーブル名だったら必ずprefixがこれになる」とか。 
全て、ユニークであればよかったのですが
テーブルの中でもヘッダーテーブルと明細テーブルで対になっているもの
例えば、T_KAIKAKE_HEAD(買掛ヘッダ)、T_KAIKAKE_DETAIL(買掛明細)みたいな
感じのテーブルは同じプリフィックス(中途半端(笑))です。
それ以外はテーブル単位でプリフィックスが異なりますが
「_LASTDATE」とかは全て共通カラム名になってます。
現状はORACLEなのですが、昨今のORACLEの導入コストが半端なく上がっているので
ORACLE⇒SQLServerへ変更を行います。そのため最悪、現状のものは、データ移行時に
新規の全テーブル共通のカラム名を全テーブルに追加してそちらにデータを移行することで
回避できそうですが、設定等でどうにかできるのであれば現状のカラム使いたいと思っています。
設定等でなんとかなりますでしょうか?

以上、宜しくお願い致します。


2019年6月17日月曜日 18時11分23秒 UTC+9 jflute:

kubo

unread,
Jun 17, 2019, 11:08:30 AM6/17/19
to DBFluteユーザの集い
jfluteです

> ORACLE⇒SQLServerへ変更を行います。そのため最悪、現状のものは、データ移行時に
> 新規の全テーブル共通のカラム名を全テーブルに追加してそちらにデータを移行することで
> 回避できそうですが、設定等でどうにかできるのであれば現状のカラム使いたいと思っています。
> 設定等でなんとかなりますでしょうか?

まず、DBFluteとしては共通カラムという名前なので、同じ名前を前提にしています。
大昔、一回だけ「テーブル名 + LASTDATE」的な案件があって、
その規則的なケースだけ対応できるようにした記憶があります。
一応テストコードがありました。
https://github.com/dbflute-test/dbflute-test-dbms-sqlite/blob/master/dbflute_maihamadb/dfprop/commonColumnMap.dfprop#L37

; $-TABLE_NAME_REGISTER_DATETIME=TIMESTAMP ; $-TABLE_NAME_REGISTER_USER=VARCHAR

(そもそも.NET版に入ってるかちょっと不明というのもありますが)
完全にそれ専用のコードなので、規則的でなければ適用できないと思います。

DB設計的にも共通カラムは同じカラムにしたほうが何かと扱いやすいので、
申し訳ないですがDBFluteとして特別な対応をする予定もないです。

志水正幸

unread,
Jun 17, 2019, 8:55:46 PM6/17/19
to DBFluteユーザの集い
志水です。



(そもそも.NET版に入ってるかちょっと不明というのもありますが)
完全にそれ専用のコードなので、規則的でなければ適用できないと思います。

DB設計的にも共通カラムは同じカラムにしたほうが何かと扱いやすいので、
申し訳ないですがDBFluteとして特別な対応をする予定もないです。
やはり規則的でないと難しいようですね。
今回の案件はプリフィックスがテーブル名でもないしちょっと簡単ではないようですね。
やはり、共通カラム名追加&データ移行で回避しようと思います。
ありがとうございました。


Reply all
Reply to author
Forward
0 new messages