并排加入两个查询

时间:2012-06-06 08:09:21

标签: sql oracle oracle11g

我需要帮助加入以下两个查询。我是Oracle的新手。我在这里查看了帖子,但提到的联接是针对简单查询的。请帮我一起显示以下两个查询的结果。

(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

第二个查询是

(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

2 个答案:

答案 0 :(得分:5)

这些查询之间唯一的共同列是branch所以我假设你想要关闭并打开每个分支的帐户数量。

首先,这些查询有很多无关的信息; only select what you need to。其次你应该使用显式连接。它们更加清晰,删除了可能发生错误的明显点,并作为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。这使您只能扫描两次而不是三次,然后避免像现在这样做full outer join

请原谅我,如果我的联接略有错误;我可能会错误地将它们转换为显式连接语法。我已经删除了你加入的一些条件,因为它们应该在那里。

作为一个小小的注意事项,您担心您的查询“复杂”应该不用担心。从本质上讲,无论您的查询多长时间,您都可以将其视为最简单的查询;只要知道你认为应该返回哪些数据,并准备好调查是否有错误。

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

对不起,我不能为所有事情做同样的事情。

进一步阅读:

答案 1 :(得分:0)

select 
    branches.branch_code,
    first_query."No of Accounts Opened",
    second_query."No of Accounts Closed"
from
   (select distinct branch_code from STTMS_CUST_ACCOUNT) branches
   left outer join (
       -- first query here
   ) first_query on branches.branch_code = first_query.Branch
   left outer join (
       -- second query here
   ) second_query on branches.branch_code = second_query.Branch

因为您没有为分支提供单独的表,所以我们必须在第一个别名中执行select distinct。如果你有另一张表只包含这些信息,最好再使用它。

我应该补充说,您的查询似乎可能会被简化(看起来您不会使用您获取的所有字段)。