我有2张桌子。
我想使用 BAL 表中的 current_balance 填充 TRAN 表中的帐号结果以及运行余额。 (最后一行应该有current_balance,前一行应该有之前的余额,即current_balance减去交易金额)
这两个表中的数据如下所示:
这是我希望输出的样子:
这是我尝试使用的代码:
SELECT
A.ACCOUNT_NO,
A.TRANSACTION_DATE,
A.TRANSACTION_AMOUNT,
B.CURRENT_BALANCE - LAG(A.TRANSACTION_AMOUNT) OVER (ORDER BY A.TRANSACTION_DATE) RUNNING_BALANCE
FROM TRAN A
INNER JOIN BAL B ON A.ACCOUNT_NO=B.ACCOUNT_NO
WHERE A.ACCOUNT_NO='11111111';
我得到以下输出:
我需要对查询进行哪些更改才能获得“我想要的输出”?
当您可以通过一张桌子保持运行平衡时,为什么还要保留两张桌子?
我也做了类似的事情。您可能想看看我的解决方案。
ALTER SESSION SET NLS_DATE_FORMAT = 'DD-MON-YYYY HH24:MI:SS';
CREATE TABLE CUSTOMERS (
CUSTOMER_ID, FIRST_NAME, LAST_NAME,IS_ACTIVE) AS
SELECT 'E379466', 'Bonnie', 'Winterbottom','Y' FROM DUAL UNION ALL
SELECT 'Z098555', 'Peter', 'Clemenza','Y' FROM DUAL;
CREATE TABLE CUSTOMER_ACCOUNTS (
ACCOUNT_NUMBER,
CUSTOMER_ID, VENDOR_ID,
IS_ACTIVE) AS
SELECT 'THVQD6M9LR7AVK', 'E379466', 1, 'Y' FROM DUAL UNION ALL
SELECT '0Z76WT5NTLRZPTW',
'Z098555', 1, 'Y' FROM DUAL;
create table transactions (
transaction_id NUMBER GENERATED BY DEFAULT AS IDENTITY,
account_number VARCHAR2(15),
transaction_type varchar2(1) DEFAULT 'C',
transaction_amount NUMBER(10,2),
transaction_date DATE DEFAULT SYSDATE
);
insert into transactions(
account_number, transaction_type, transaction_amount, transaction_date)
SELECT '0Z76WT5NTLRZPTW', 'D', (LEVEL * 100.57), date '2023-04-02' + level * interval '1 4' day to hour from dual
connect by level <= 5
union all
SELECT '0Z76WT5NTLRZPTW', 'C', (LEVEL * 25.26), date '2023-04-04' + level * interval '1 4' day to hour from dual
connect by level <= 5
union all
SELECT 'THVQD6M9LR7AVK', 'D', (LEVEL * 50.10), date '2023-05-10' + level * interval '1 7' day to hour from dual
connect by level <= 13
union all
SELECT 'THVQD6M9LR7AVK', 'D', (LEVEL * 33.11), date '2023-05-10' + level * interval '1 7' day to hour from dual
connect by level <= 9;
CREATE OR REPLACE FUNCTION get_customer_balance
( i_customer_id IN customers.customer_id%TYPE
)
RETURN transactions.transaction_amount%TYPE
IS
v_balance transactions.transaction_amount%TYPE;
BEGIN
SELECT SUM (
CASE t.transaction_type
WHEN 'C'
THEN -t.transaction_amount
ELSE t.transaction_amount
END
)
INTO v_balance
FROM customer_accounts ca
JOIN transactions t ON t.account_number = ca.account_number
WHERE ca.customer_id = i_customer_id -- one customer
OR ca.customer_id IS NULL; -- all customers
RETURN v_balance;
END get_customer_balance;
/
CREATE OR REPLACE FUNCTION get_account_balance(
i_account_number IN TRANSACTIONS.ACCOUNT_NUMBER%TYPE
) RETURN TRANSACTIONS.TRANSACTION_AMOUNT%TYPE
IS
v_balance TRANSACTIONS.TRANSACTION_AMOUNT%TYPE;
BEGIN
SELECT SUM(
CASE transaction_type WHEN 'C' THEN -1 ELSE 1 END
* transaction_amount
)
INTO v_balance
FROM transactions
WHERE account_number = i_account_number -- one account
OR i_account_number IS NULL; -- all accounts
RETURN v_balance;
END;
/
SELECT CA.ACCOUNT_NUMBER,
C.FIRST_NAME,
C.LAST_NAME,
CA.IS_ACTIVE,
get_account_balance(ca.account_number) AS balance
FROM CUSTOMER_ACCOUNTS CA
INNER JOIN customers c
ON ca.customer_id = c.customer_id;
/* transaction history for an account */
WITH daily_summary AS
(
SELECT
account_number,
transaction_date
, SUM (DECODE (transaction_type, 'C', transaction_amount, 0)) AS credit_total
, SUM (DECODE (transaction_type, 'D', transaction_amount , 0)) AS debit_total
FROM transactions
GROUP BY account_number, transaction_date
)
SELECT d.*
, SUM (debit_total - credit_total)
OVER (ORDER BY transaction_date) AS balance_to_date
FROM daily_summary d
WHERE account_number =
'0Z76WT5NTLRZPTW'
ORDER BY transaction_date;