[seasar-dotnet:1868] Re: [DBFlute.NET]業務的one-to-oneな条件に他テーブルのカラム値指定

fp [E-MAIL ADDRESS DELETED]
2010年 10月 12日 (火) 01:25:54 JST


fpです。

久保さん、ありがとうございます。

無理のない範囲で宜しくお願いします。
(既に大抵無理言ってしまってますが)

(2010/10/12 1:03), kubo wrote:
> 久保(jflute)です。
> 
>> 私の想定するSQLは単純に以下の通りです。
>>
>> select ...
>>   from MEMBER dflocal
>>     left outer join MEMBER_LOGIN dfrelation_4
>>       on dflocal.MEMBER_ID = dfrelation_4.MEMBER_ID
>>     left outer join MEMBER_STATUS dfrelation_4_1
>>       on dfrelation_4.LOGIN_MEMBER_STATUS_CODE =
>> dfrelation_4_1.MEMBER_STATUS_CODE
>>      and dfrelation_4_1.DISPLAY_ORDER = 2
> 
> なるほど、MEMBER_LOGIN の自体の on 句に入るのではなく、
> その先のMEMBER_STATUS の on 句に指定した条件を入れる
> イメージでしたか。で、そのように条件付けると、
> 業務的には MEMBER からone-to-oneになると。
> 
> fixedConditionは、現状ではMEMBER_LOGIN の join の on 句の
> 条件を指定することが大前提となっていますので、その土台のまま
> ではそのようなSQLは作ることはできません。
> なので、実現するには MEMBER_STATUS の on 句の方に
> 指定できるような新しい仕組みが必要ですね。
> 考えられるのが以下のパターン:
> 
> A. MEMBER_LOGIN の on 句に条件を入れるパターン(通常)
> B. MEMBER_STATUS の on 句に条件を入れるパターン(新)
> C. 両方の on 句に条件を入れるパターン(新)
> D. Cに加えて、さらに先の関連テーブルにも入れるパターン(新)
> 
> fpさんの要件では B というところですね。
> これはこれで、ほぼ新機能と言っていいもので、
> 特に「dfpropでどう指定させるのか」を
> 時間掛けて練る必要がありそうです。
> (fixedConditionに加えてoverConditionという項目を追加とか、
> fixedConditionの中で自動判別させて条件の嫁ぎ先を決定するとか)
> 
> とりあえずは一旦、上記以外のパターンの実装を固めて、
> SNAPSHOT 出したいと思います。上記以外のパターンだけでも
> 業務的one-to-oneがしっかりと使えるように。
> (どうしても Java to C# で、ちょっとC#版が遅れるので段階的に)
> 
> また、ひとまず以下のようなSQLが自動解決できれば、
> それはそれで役に立ちそうなので、できるようにしてみようかと。
> (一応、B のパターンと同じ動作になり得るかなと)
> 
> select *
>   from member dflocal
>     left outer join
>       (select MEMBER_LOGIN.*, dfrelation_4_1.DISPLAY_ORDER
>          from MEMBER_LOGIN
>          left outer join MEMBER_STATUS dfrelation_4_1
>            on MEMBER_LOGIN.LOGIN_MEMBER_STATUS_CODE =
> dfrelation_4_1.MEMBER_STATUS_CODE
>       ) dfrelation_4
>       on dflocal.MEMBER_ID = dfrelation_4.MEMBER_ID
>      and dfrelation_4.DISPLAY_ORDER = 2
> 
> dfprop において、fixedConditionの中に
> $$over(!foreignTable!.memberStatus)$$.DISPLAY_ORDER
> というように指定があれば、InlineViewを自動で展開して、
> DISPLAY_ORDER だけを select 句に追加して、
> MEMBER_LOGINのエリアス名経由でDISPLAY_ORDERが
> 利用できるように。
> (って書いておいてできなかったりして...一応半分くらいできてて)
> 
> 2010/10/11 fp<[E-MAIL ADDRESS DELETED]>:
>> fpです。
>>
>> 久保さん、こんばんは、ありがとうございます。
>>
>> 今まで良く分かっていなかったのですが、
>> このレスで何となく久保さんの仰る曖昧さの意味が
>> 分かったような気がします。
>> ほんと申し訳ありません。
>>
>> 「二つの left outer join が、互いに参照し合う」
>> というのが問題ですね。
>>
>> 私の想定するSQLは単純に以下の通りです。
>>
>> select ...
>>   from MEMBER dflocal
>>     left outer join MEMBER_LOGIN dfrelation_4
>>       on dflocal.MEMBER_ID = dfrelation_4.MEMBER_ID
>>     left outer join MEMBER_STATUS dfrelation_4_1
>>       on dfrelation_4.LOGIN_MEMBER_STATUS_CODE =
>> dfrelation_4_1.MEMBER_STATUS_CODE
>>      and dfrelation_4_1.DISPLAY_ORDER = 2
>>
>> イメージとしては、dfpropで
>> $$over($$foreignAlias$$.overRelationAlias)$$
>> と指定したら
>>
>> $$localAlias$$
>> left outer join
>> $$foreignAlias$$
>>   on $$localAlias$$.ID = $$foreignAlias$$.ID
>> left outer join
>> $$overRelationAlias$$
>>   on $$foreignAlias$$.overRelationAlias_ID = $$overRelationAlias$$.ID
>> and [fixedCondition]
>>
>> です。
>>
>> $$over($$localAlias$$.overRelationAlias)$$
>> なら
>>
>> $$localAlias$$
>> left outer join
>> $$foreignAlias$$
>>   on $$localAlias$$.ID = $$foreignAlias$$.ID
>> left outer join
>> $$overRelationAlias$$
>>   on $$localAlias$$.overRelationAlias_ID = $$overRelationAlias$$.ID
>> and [fixedCondition]
>>
>> で、
>> $$over(dflocal.overRelationAlias)$$
>> なら
>>
>> from dflocal
>> left outer join
>> $$localAlias$$
>>   on dflocal.localAlias_ID = $$localAlias$$.ID
>> left outer join
>> $$foreignAlias$$
>>   on $$localAlias$$.ID = $$foreignAlias$$.ID
>> left outer join
>> $$overRelationAlias$$
>>   on dflocal.overRelationAlias_ID = $$overRelationAlias$$.ID
>> and [fixedCondition]
>>
>> で、いけるのかなと。
>>
>> ※  [fixedCondition]は
>>     $$overRelationAlias$$.XxxColumn = $cls(XxxType.XxxCode)
>> とか
>>     $$foreignAlias$$.XxxColumn = $$overRelationAlias$$.XxxColumn
>> とか
>>     $$localAlias$$.XxxColumn<= $$overRelationAlias$$.XxxColumn
>> とか
>>     dflocal.XxxColumn>= $$overRelationAlias$$.XxxColumn
>> です。
>>
>> 長々とすみません。宜しくお願いします。
>>
>>
>> (2010/10/11 22:37), kubo wrote:
>>> 久保(jflute)です。
>>>
>>> fpさん、もうちょっとアドバイス頂ければと思います。
>>> 定義した業務的one-to-oneの foreignTable を経由した
>>> さらなる foreignTable のカラムを fixedCondition に
>>> 利用するパターンですが、二つの left outer join が、
>>> 互いに参照し合うのでSQL的に動作するのかどうか、
>>> ちょっと疑問に思っています。
>>>
>>> local = MEMBER
>>> foreign = MEMBER_LOGIN (業務的one-to-one)
>>> foreignのforeign = MEMBER_STATUS (LOGIN経由)
>>>
>>> select ...
>>>     from member dflocal
>>>       left outer join MEMBER_STATUS dfrelation_4_1
>>>         on dfrelation_4.LOGIN_MEMBER_STATUS_CODE =
>>> dfrelation_4_1.MEMBER_STATUS_CODE
>>>       left outer join MEMBER_LOGIN dfrelation_4
>>>         on dflocal.MEMBER_ID = dfrelation_4.MEMBER_ID
>>>        and dfrelation_4_1.DISPLAY_ORDER = 2
>>>
>>> だと、MEMBER_STATUS の left outer join が先に来て、
>>> dfrelation_4 が(まだ)解決できません。順番を逆にしても:
>>>
>>> select ...
>>>     from member dflocal
>>>       left outer join MEMBER_LOGIN dfrelation_4
>>>         on dflocal.MEMBER_ID = dfrelation_4.MEMBER_ID
>>>        and dfrelation_4_1.DISPLAY_ORDER = 2
>>>       left outer join MEMBER_STATUS dfrelation_4_1
>>>         on dfrelation_4.LOGIN_MEMBER_STATUS_CODE =
>>> dfrelation_4_1.MEMBER_STATUS_CODE
>>>
>>> 今度は、MEMBER_LOGIN の on 句で、
>>> dfrelation_4_1 が解決できません。
>>> MySQLとPostgreSQLで実際に試してエラーになりました。
>>>
>>> 頭の中でいけるかなぁと勝手に思っていはいたのですが、
>>> いざやってみると確かに...。
>>> ちょっと自分が勘違いしているかもしれません。
>>> fpさんのところで実業務で想定しているパターンを
>>> もう少し情報頂けないでしょうか?
>>> (どういうSQLを想定されていますでしょうか!?)
>>>
>>> #
>>> # 以下のようにすれば、いけそうですが、
>>> # 同名カラムをどう解決したものかってとこですね...
>>> #
>>>
>>> select *
>>>     from member dflocal
>>>       left outer join
>>>         (select *
>>>            from MEMBER_LOGIN
>>>            left outer join MEMBER_STATUS dfrelation_4_1
>>>              on MEMBER_LOGIN.LOGIN_MEMBER_STATUS_CODE =
>>> dfrelation_4_1.MEMBER_STATUS_CODE
>>>         ) dfrelation_4
>>>         on dflocal.MEMBER_ID = dfrelation_4.MEMBER_ID
>>>        and dfrelation_4.DISPLAY_ORDER = 2
>>>
>>>
>>> 2010/10/11 fp<[E-MAIL ADDRESS DELETED]>:
>>>> fpです。
>>>>
>>>> ありがとうございます。
>>>>
>>>> 申し訳ありませんが、宜しくお願いします。
>>>>
>>>> (2010/10/11 18:46), kubo wrote:
>>>>> 久保(jflute)です。
>>>>>
>>>>>> 当方のプロジェクトでは、話に出た全パターン当てはまります。
>>>>> なるほどー、じゃあ頑張りますよぅ。
>>>>> こっちも「すぐに使ってもらえないかもしれない機能」を
>>>>> 実装するのはリスクがあって、すぐに確認・実践してもらえる
>>>>> ことで、要件に合った仕様と品質を担保してから公開できるので。
>>>>> (なので、大分安定を重視する時期に来たDBFluteでは要件のない
>>>>> 機能はあえて実装せずに将来の機会を待つこともあります、
>>>>> 今回のパターンはそのつもりでした...)
>>>>> もちろん、実現コストに全て委ねられますが、あともうちょい頑張れば
>>>>> できそうなので。(フィルタ処理はコールバックで遅延させます)
>>>>>
>>>>> 2010/10/11 fp<[E-MAIL ADDRESS DELETED]>:
>>>>>> fpです。
>>>>>>
>>>>>> 久保さん、ありがとうございます。
>>>>>>
>>>>>> 当方のプロジェクトでは、話に出た全パターン当てはまります。
>>>>>>
>>>>>> ただ、無理なようでしたら機能制限の範囲内で回避策を
>>>>>> 考えますので、それほど緊急とはお考えにならないで下さい。
>>>>>>
>>>>>>
>>>>>>
>>>>>> すれちがってしまいましたね。>[seasar-dotnet:1861]
>>>>>>
>>>>>>
>>>>>> (2010/10/11 18:26), kubo wrote:
>>>>>>> 久保(jflute)です。
>>>>>>>
>>>>>>> ああ、なるほど、業務的one-to-oneのリレーションを
>>>>>>> 通過した先の foreignTable のことですね。
>>>>>>> しかも、今の仕様だと辿るリレーションの中で、
>>>>>>> 業務的one-to-oneを含めることができないので、
>>>>>>> 参照元テーブルから辿ることもできないですね。
>>>>>>>
>>>>>>> 業務的one-to-oneの参照先テーブルだけは特別に、
>>>>>>> ポイントとして指定できる唯一の foreignTable、
>>>>>>> もしくは、リレーションで特別に辿れる業務的one-to-one
>>>>>>> というように扱えればってところですね。
>>>>>>>
>>>>>>> $$over(MEMBER_LOGIN.memberStatus)$$
>>>>>>>
>>>>>>>       もしくは
>>>>>>>
>>>>>>> $$over(MEMBER.memberLoginAsValid.memberStatus)$$
>>>>>>>
>>>>>>> 該当の業務的one-to-oneが確定していない時点で、その奥の
>>>>>>> リレーションを有効にしてエリアス名を取得できるかどうか、
>>>>>>> その辺が実現の鍵になるので、ちょっと考えますね。
>>>>>>> (場合に寄っては、置換処理をコールバックで遅延させて
>>>>>>> 実行させるなどの工夫が必要かも...)
>>>>>>>
>>>>>>> ちなみに、fp さんの業務の中で、このパターンに
>>>>>>> 当てはまるものがありますでしょうか?
>>>>>>>
>>>>>>> 2010/10/11 fp<[E-MAIL ADDRESS DELETED]>:
>>>>>>>> fpです。
>>>>>>>>
>>>>>>>> 「OverRelation」を使わずに以下のようにできることは
>>>>>>>> 認識しています。
>>>>>>>>
>>>>>>>> ; FK_MEMBER_MEMBER_LOGIN_AS_VALID = map:{
>>>>>>>>         ; localTableName  = MEMBER    ; foreignTableName  = MEMBER_LOGIN
>>>>>>>>         ; localColumnName = MEMBER_ID ; foreignColumnName = MEMBER_ID
>>>>>>>>         ; fixedCondition =
>>>>>>>>           exists(select 'TRUE' from MEMBER_STATUS st
>>>>>>>>                   where $$foreignAlias$$.LOGIN_MEMBER_STATUS_CODE =
>>>>>>>>                         st.MEMBER_STATUS_CODE
>>>>>>>>                     and st.DISPLAY_ORDER = 2)
>>>>>>>>         ; fixedSuffix = AsValid
>>>>>>>> }
>>>>>>>>
>>>>>>>>
>>>>>>>> (2010/10/11 16:44), fp wrote:
>>>>>>>>> fpです。
>>>>>>>>>
>>>>>>>>> 久保さん、即座の御返事ありがとうございます。
>>>>>>>>>
>>>>>>>>> ん〜、dbflute_exampledb にうまい例が見つからないのですが
>>>>>>>>> 仮に、MEMBER ->          MEMBER_LOGIN ->          MEMBER_STATUS で
>>>>>>>>> MEMBER_STATUS.DISPLAY_ORDER = 2 の条件で
>>>>>>>>> MEMBER ->          MEMBER_LOGIN に業務的one-to-oneなFKを設定できる
>>>>>>>>> とした場合、
>>>>>>>>>
>>>>>>>>> ; FK_MEMBER_MEMBER_LOGIN_AS_VALID = map:{
>>>>>>>>>          ; localTableName  = MEMBER    ; foreignTableName  = MEMBER_LOGIN
>>>>>>>>>          ; localColumnName = MEMBER_ID ; foreignColumnName = MEMBER_ID
>>>>>>>>>          ; fixedCondition =
>>>>>>>>>              $$over(MEMBER_LOGIN.memberStatus)$$.DISPLAY_ORDER = 2
>>>>>>>>>          ; fixedSuffix = AsValid
>>>>>>>>> }
>>>>>>>>> と書きたい、ということです。
>>>>>>>>> 定義上明示されている MEMBER_LOGIN をポイントテーブルと
>>>>>>>>> することに曖昧さがあるとは思わないのですが。
>>>>>>>>>
>>>>>>>>> いままさに定義しようとしているリレーションのための
>>>>>>>>> 条件の指定に、以下は適用できませんし。
>>>>>>>>>> MEMBER.memberStatusByFooCode というように、
>>>>>>>>>> 明示的にリレーションを書いてもらう仕様にしています。
>>>>>>>>>
>>>>>>>>> foreignTable についての認識に齟齬があるのでしょうか?
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> (2010/10/11 15:56), kubo wrote:
>>>>>>>>>> 久保(jflute)です。
>>>>>>>>>>
>>>>>>>>>>> とはいえ、foreignTable をポイントとすることはできないでしょうか?
>>>>>>>>>>
>>>>>>>>>> 例えば、会員に会員ステータスへのFKカラムが二つあった場合、
>>>>>>>>>> ポイントを会員ステータスにするとになります。
>>>>>>>>>> なので、foreignTableに関しては、
>>>>>>>>>> MEMBER.memberStatusByFooCode というように、
>>>>>>>>>> 明示的にリレーションを書いてもらう仕様にしています。
>>>>>>>>>> 親の親の親の親の親のカラムとかになると、指定が長くて
>>>>>>>>>> 大変ですが、曖昧さの可能性も増えるので、
>>>>>>>>>> そこの優先度を練り直したって感じです。
>>>>>>>>>>
>>>>>>>>>>>> ポイントテーブルは ORDER_ITEM で、リレーションは order。
>>>>>>>>>>>>         ->             $$over(ORDER_ITEM.order)$$
>>>>>>>>>>>
>>>>>>>>>>> これは実際の構成ではなく、あくまで例ってことで (^^;
>>>>>>>>>>
>>>>>>>>>> おっと、そうでしたかぁ、失敬w
>>>>>>>> _______________________________________________
>>>>>>>> seasar-dotnet mailing list
>>>>>>>> [E-MAIL ADDRESS DELETED]
>>>>>>>> https://ml.seasar.org/mailman/listinfo/seasar-dotnet
>>>>>>>>
>>>>>>> _______________________________________________
>>>>>>> seasar-dotnet mailing list
>>>>>>> [E-MAIL ADDRESS DELETED]
>>>>>>> https://ml.seasar.org/mailman/listinfo/seasar-dotnet
>>>>>>
>>>>>> _______________________________________________
>>>>>> seasar-dotnet mailing list
>>>>>> [E-MAIL ADDRESS DELETED]
>>>>>> https://ml.seasar.org/mailman/listinfo/seasar-dotnet
>>>>>>
>>>>> _______________________________________________
>>>>> seasar-dotnet mailing list
>>>>> [E-MAIL ADDRESS DELETED]
>>>>> https://ml.seasar.org/mailman/listinfo/seasar-dotnet
>>>>
>>>> _______________________________________________
>>>> seasar-dotnet mailing list
>>>> [E-MAIL ADDRESS DELETED]
>>>> https://ml.seasar.org/mailman/listinfo/seasar-dotnet
>>>>
>>> _______________________________________________
>>> seasar-dotnet mailing list
>>> [E-MAIL ADDRESS DELETED]
>>> https://ml.seasar.org/mailman/listinfo/seasar-dotnet
>>
>> _______________________________________________
>> seasar-dotnet mailing list
>> [E-MAIL ADDRESS DELETED]
>> https://ml.seasar.org/mailman/listinfo/seasar-dotnet
>>
> _______________________________________________
> seasar-dotnet mailing list
> [E-MAIL ADDRESS DELETED]
> https://ml.seasar.org/mailman/listinfo/seasar-dotnet



seasar-dotnet メーリングリストの案内