【问题标题】:Solving problem using enhanced aggregate reporting functions in Oracle在 Oracle 中使用增强的聚合报告功能解决问题
【发布时间】:2019-02-22 17:42:31
【问题描述】:

我正在使用 sqlplus (oracle)。 我试图写一个语句来显示基于所有交易价值的账户价值变化

  • 每个 customer_account_combination
  • 每位客户
  • 全行

此外,借方交易应为负数,贷方交易应保持为正数。 我需要在 oracle 中使用增强的聚合报告功能来解决它​​。 另外,应该有客户总数和总计。

这是我到目前为止所得到的。

select wc.first_name "First", wc.surname "Last", wt.account_type "Act Type" 
case when wt.transaction_type is NULL then NULL 
    when wt.transaction_type = 'D'then TO_CHAR(transaction_amount*-1, '$9,999.99') 
    else TO_CHAR(transaction_amount, '$9,999.99') 
    end "Total" 
from wgb_customer wc join wgb_account wa on wa.customer_number = wc.customer_number join wgb_account_type wt on wa.account_type = wt.account_type
left outer join wgb_transaction wt on wt.customer_number = wa.customer_number 
and wt.account_type = wa.account_type
order by 2,3,6;

但是,它不起作用,并且不显示客户总数或总计。 请帮忙!

ERD

预期输出

【问题讨论】:

  • 现在不在我的电脑后面向您展示示例,但您正在寻找的是“GROUP BY CUBE”或“GROUP BY ROLLUP”。它允许您开箱即用地生成小计和总计。
  • 选择 wc.first_name "First", wc.surname "Last", wa.account_type "Type", SUM(transaction_amount) AS wt.transaction_type 为 NULL 时的总情况,然后 wt.transaction_type = NULL 'D'then TO_CHAR(transaction_amount*-1, '$9,999.99') else TO_CHAR(transaction_amount, '$9,999.99') end "Total" from wgb_customer wc, wgb_account wa, wgb_transaction wt where wc.customer_number=wa.customer_number and wa.account_type= wt.account_type GROUP BY ROLLUP (first_name, surname, account_type, transaction_amount) order by 2,3;
  • 我想出了上面的评论,但它不起作用:(
  • 提供样本输入和预期输出。
  • 我已将预期输出附加为图像

标签: sql oracle sqlplus


【解决方案1】:

GROUP BY ROLLUP 是要走的路。它允许您创建所有可能的小计和总计。聚合数据后,您只需将连接保留到客户表以检索 first_name 和 last_name。确保进行左连接,以免丢失总数

--SAMPLE TABLES AND TEST DATA 

  CREATE TABLE WGB_TRANSACTION (
    CUSTOMER_NUMBER VARCHAR2(7),
    ACCOUNT_TYPE NUMBER(1),
    TRANSACTION_AMOUNT NUMBER,
    TRANSACTION_TYPE VARCHAR2(1)
  );

  CREATE TABLE WGB_CUSTOMER (
    CUSTOMER_NUMBER VARCHAR2(7),
    FIRST_NAME VARCHAR2(30),
    SURNAME VARCHAR2(30)
   );

INSERT INTO WGB_CUSTOMER VALUES ( '123', 'John','Smith');
INSERT INTO WGB_CUSTOMER VALUES ( '456', 'James','Anderson');
INSERT INTO WGB_TRANSACTION VALUES (123,1,100,'C');
INSERT INTO WGB_TRANSACTION VALUES (123,1,50,'D');
INSERT INTO WGB_TRANSACTION VALUES (123,2,100,'C');
INSERT INTO WGB_TRANSACTION VALUES (456,1,50,'C');
INSERT INTO WGB_TRANSACTION VALUES (456,1,100,'C');
INSERT INTO WGB_TRANSACTION VALUES (456,3,100,'D');
INSERT INTO WGB_TRANSACTION VALUES (456,1,50,'C');

--The Query 
WITH BALANCES AS (
    SELECT CUSTOMER_NUMBER, ACCOUNT_TYPE, 
    SUM(DECODE(TRANSACTION_TYPE,'D',-1,'C',1,0)*TRANSACTION_AMOUNT) BALANCE
    FROM WGB_TRANSACTION WHERE TRANSACTION_TYPE IN ('C','D') 
    GROUP BY ROLLUP ( CUSTOMER_NUMBER, ACCOUNT_TYPE )
)
SELECT C.FIRST_NAME, C.SURNAME, B.ACCOUNT_TYPE, TO_CHAR(B.BALANCE,'$9,999.99')
FROM BALANCES B LEFT JOIN WGB_CUSTOMER C ON C.CUSTOMER_NUMBER=B.CUSTOMER_NUMBER;

--RESULT 
FIRST_NAME  SURNAME ACCOUNT_TYPE    TO_CHAR(B.BALANCE,'$9,999.99')
John    Smith   (null)  $150.00
John    Smith   2   $100.00
John    Smith   1   $50.00
James   Anderson    (null)  $100.00
James   Anderson    3   -$100.00
James   Anderson    1   $200.00
(null)  (null)  (null)  $250.00

【讨论】:

    【解决方案2】:

    使用联合

        select wc.first_name "First", wc.surname "Last", wt.account_type "Act Type" 
        case when wt.transaction_type is NULL then NULL 
            when wt.transaction_type = 'D'then TO_CHAR(transaction_amount*-1, '$9,999.99') 
            else TO_CHAR(transaction_amount, '$9,999.99') 
            end "Total" 
        from wgb_customer wc join wgb_account wa on wa.customer_number = wc.customer_number join wgb_account_type wt on wa.account_type = wt.account_type
        left outer join wgb_transaction wt on wt.customer_number = wa.customer_number 
        and wt.account_type = wa.account_type
    union 
     select '','',TO_CHAR(total,'$9,999.99') from 
    (
    select  
           sum ( case when wt.transaction_type is NULL then 0
            when wt.transaction_type = 'D' then transaction_amount*-1 
            else transaction_amount
            end ) as total
        from wgb_customer wc join wgb_account wa on wa.customer_number = wc.customer_number join wgb_account_type wt on wa.account_type = wt.account_type
        left outer join wgb_transaction wt on wt.customer_number = wa.customer_number 
        and wt.account_type = wa.account_type
    ) t
    

    【讨论】:

      猜你喜欢
      • 2011-10-25
      • 2011-05-08
      • 1970-01-01
      • 1970-01-01
      • 2018-11-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-11-12
      相关资源
      最近更新 更多