3

以下の 2 つのクエリを結合する際に助けが必要です。私はオラクルが初めてです。ここで投稿を確認しましたが、言及されている結合は単純なクエリ用です。以下の 2 つのクエリの結果を並べて表示するのを手伝ってください。

(select Branch, count(*) as "No of Accounts Opened"
      from (SELECT A.CUST_AC_NO,
                   A.CCY,
                   A.branch_code Branch,
                   A.ACY_CURR_BALANCE,
                   A.AC_OPEN_DATE,
                   B.CUSTOMER_NAME1,
                   C.LIMIT_AMOUNT,
                   D.ACCOUNT_CLASS,
                   D.DESCRIPTION
              FROM STTM_CUST_ACCOUNT  A,
                   STTM_CUSTOMER      B,
                   getm_facility      C,
                   STTM_ACCOUNT_CLASS D,
                   getm_liab_cust     e
             WHERE B.CUSTOMER_NO = A.CUST_NO
               AND A.ACCOUNT_CLASS = D.ACCOUNT_CLASS
               and c.liab_id = e.liab_id
               and e.customer_no = b.customer_no
               and e.customer_no = a.cust_no
               AND B.LIABILITY_NO = e.customer_no
               AND RTRIM(C.LINE_CoDe) || LTRIM(TO_CHAR(C.LINE_SERIAL)) =
                   RTRIM(A.LINE_ID)
               AND A.RECORD_STAT = 'O'
               and c.record_stat = 'O'
               and e.record_stat = 'O'
                  --AND to_char(A.AC_OPEN_DATE,'YYYY')=:Year
                  --AND trim(to_char(A.AC_OPEN_DATE,'Month'))=:Month
                  --AND a.BRANCH_CODE ='001'
               AND A.CCY <> 'ZWD'
            UNION
            SELECT A.CUST_AC_NO,
                   A.CCY,
                   Branch_code Branch,
                   A.ACY_CURR_BALANCE,
                   A.AC_OPEN_DATE,
                   B.CUSTOMER_NAME1,
                   NULL LIMIT_AMOUNT,
                   D.ACCOUNT_CLASS,
                   D.DESCRIPTION
              FROM STTM_CUST_ACCOUNT  A,
                   STTM_CUSTOMER      B,
                   STTM_ACCOUNT_CLASS D
             WHERE B.CUSTOMER_NO = A.CUST_NO
               AND A.ACCOUNT_CLASS = D.ACCOUNT_CLASS
               AND A.RECORD_STAT = 'O'
                  --AND to_char(A.AC_OPEN_DATE,'YYYY')=:Year
                  --AND trim(to_char(A.AC_OPEN_DATE,'Month'))=:Month
                  --AND BRANCH_CODE ='001'
               AND A.CCY <> 'ZWD')
     group by Branch
     order by Branch) A

2番目のクエリは

(select Branch,count(*) as "No of Accounts Closed"  from(SELECT
    a.branch_code Branch,
    A.CUST_AC_NO,
    A.CCY,
    A.ACY_CURR_BALANCE,
    a.maker_id,
    a.maker_dt_stamp,
    a.checker_id,
    A.CHECKER_DT_STAMP,
    B.CUSTOMER_NAME1,
    C.ACCOUNT_CLASS,
    C.DESCRIPTION
    FROM
    STTMS_CUST_ACCOUNT A,
    STTMS_CUSTOMER B,
    STTMS_ACCOUNT_CLASS C
    WHERE
    B.CUSTOMER_NO = A.CUST_NO
    AND A.ACCOUNT_CLASS = C.ACCOUNT_CLASS
    AND A.RECORD_STAT = 'C'
    ---AND A.BRANCH_CODE ='001'- :brn
    --AND trunc(to_char(A.CHECKER_DT_STAMP,'YYYY'))=:Year
    --AND trim(to_char(A.CHECKER_DT_STAMP,'Month'))=:Month
    ORDER BY
    CUSTOMER_NAME1)group by Branch order by Branch) B
4

2 に答える 2

6

これらのクエリ間の唯一の共通の列はbranch、ブランチごとに閉鎖および開設されたアカウントの数が必要であると仮定します。

まず、これらのクエリには無関係な情報がたくさん含まれています。必要なものだけを選択してください。次に、明示的な結合を実際に使用する必要があります。それらははるかに明確で、エラーが発生する可能性がある明らかなポイントを取り除き、SQL 標準として数十年にわたって使用されてきました。

あなたの質問に対する簡単で迅速な答えは次のとおりです。

select a.*, b.*
  from query1 a
  full outer join query2 b
    on a.branch = b.branch

full outer joinあるクエリのブランチが別のクエリに存在するという保証はないため、使用します。私は詳細に入ることができるとき、迅速かつ単純なファンではありません....

最善の方法は、 where 条件を に削除することsum(case when...)ですselect。これにより、テーブルを 3 回ではなく 2 回スキャンするだけで済むようfull outer joinになり、現時点で行う必要のある a の実行を回避できます。

これらの結合が少し間違っている場合は、ご容赦ください。それらを明示的な結合構文に変換すると、間違いを犯す可能性があります。参加する場所の条件の一部を削除しました。そこにあるはずです。

ちょっとした補足として、クエリが「複雑」であるという心配は心配する必要はありません。基本的に、クエリがどれだけ長くても、可能な限り単純であるかのように扱うことができます。どのデータが返されるべきかを認識し、それが間違っていると思われる場合は調査する準備をしてください。

select branch
     , sum(opened) as "number of accounts opened"
     , sum(closed) as "number of accounts closed"
   from ( select branch
               , sum(case when a.record_stat = 'C' then 1 
                          else 0 end) as closed
               , sum(case when a.record_stat = 'O' and a.ccy <> 'zwd' then 1 
                          else 0 end ) as opened
            from STTMS_CUST_ACCOUNT A
            join STTMS_CUSTOMER B
              on B.CUSTOMER_NO = A.CUST_NO
            join STTMS_ACCOUNT_CLASS C
              on A.ACCOUNT_CLASS = C.ACCOUNT_CLASS
              -- include where condition to use indexes (if possible)
           where a.record_stat in ('C','O')
           group by branch
              -- union would imply a distinct, which we don-t want.
           union all
          select branch
               , count(*) as opened
               , 0 as closed
            from STTM_CUST_ACCOUNT A
            join STTM_CUSTOMER  B
              on B.CUSTOMER_NO = A.CUST_NO
            join getm_facility C
              on rtrim(C.LINE_CoDe) || ltrim(to_char(C.LINE_SERIAL)) 
                 = rtrim(A.LINE_ID)
              -- moved from where as this is a join condition
             and a.record_stat = c.record_stat
            join STTM_ACCOUNT_CLASS D
              on A.ACCOUNT_CLASS = D.ACCOUNT_CLASS
            join getm_liab_cust e
              on c.liab_id = e.liab_id
             and e.customer_no = b.customer_no
             and e.customer_no = a.cust_no
             and b.liability_no = e.customer_no
              -- moved from where as this is a join condition
             and a.record_stat = e.record_stat
              -- only want one number returned so conditions in the where clause
           where A.RECORD_STAT = 'O'
             and A.CCY <> 'ZWD'
           group by branch
                 )
 group by branch

申し訳ありませんが、すべてを同じように扱うことはできませんでした。

参考文献:

于 2012-06-06T08:44:16.617 に答える