Uploaded image for project: 'DBFlute'
  1. DBFlute
  2. DBFLUTE-379

{Java}: 最大値レコードを検索(ScalarSubQuery)

XMLWordPrintable

    • Type: Icon: Improvement Improvement
    • Resolution: Fixed
    • Priority: Icon: Minor Minor
    • Component/s: None
    • None

      SQL的にはこう:

      select *
        from MEMBER
       where REGISTER_DATE = (
         select max(REGISTER_DATE)
           from MEMBER
          where ...
       )
      

      上記の例のパターンがそのまま業務的に一番よく使われると思われる。
      Where句は「論理削除されてないもの」など利用されることは多いはず。
      これも確かに「目的はシンプルなのにSQLでシンプルに書けない」部類の一つである。
      そして実現可能性的にはSpecifyDerivedReferrerの応用でできそうである。

      演算子は「=, >=, >, <=, <」のみサポート。
      メソッド数を増やさず(※1)に柔軟に対応できるi/Fが思いつけば良いが、
      そうでなければ「最大値レコードを取りたい」という「等値」限定の機能でも良い。
      (その場合はmax()/min()限定で良いと思われる)
      ※1 = 「テーブル数 × カラム数 × 演算子」にならないように

      それらを考慮したI/Fで考えつくのはこういうのである。

      // 登録日時が最大(一番最近)の会員を検索
      MemberCB cb = new MemberCB();
      cb.query().scalar_Equal().max(new SubQuery() {
          public void query(MemberCB subCB) {
              subCB.specify().columnRegisterDatetime(); // *Required
              subCB.query().setXxx...
          }
      });
      
      // 会員レベルが平均値より高い会員を検索
      MemberCB cb = new MemberCB();
      cb.query().scalar_GreaterEqual().avg(new SubQuery() {
          public void query(MemberCB subCB) {
              subCB.specify().columnMemberLevel(); // *Required
              subCB.query().setXxx...
          }
      });
      

      これならメソッド数が膨大になることはない(テーブル数×演算子で済む)。

      しかしながら、ここまでできると今度は比較対象のカラムを別のカラムにしたい
      とかいう話にもなるが、複雑で安全性が一気に無くなるので(型の違いとか)
      そこはばっさり割り切ることにする。

      それにしても早くクロージャが欲しいよぉ

            Assignee:
            jflute jflute
            Reporter:
            jflute jflute
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

              Created:
              Updated:
              Resolved: