1

我有这样的表:

cust_id acc_no trans_id  trans_type amount
1111    1001    10   credit     2000.0  
1111    1001    11   credit     1000.0
1111    1001    12   debit      1000.0  
2222    1002    13   credit     2000.0  
2222    1002    14   debit      1000.0

我想要一个客户完成的每笔交易的 Hive 查询或 sql 查询,余额应该这样计算。

我想要输出如下:

cust_id acc_no trans_id  trans_type amount      balance
1111.0  1001.0  10.0     credit    2000.0   2000.0
1111.0  1001.0  11.0     credit    1000.0   3000.0
1111.0  1001.0  12.0     debit     1000.0   2000.0
2222.0  1002.0  13.0     credit    2000.0   2000.0
2222.0  1002.0  14.0     debit     1000.0   1000.0

我试过了

SELECT * 
FROM   (SELECT cust_id, 
               acc_no, 
               trans_id, 
               trans_type, 
               amount, 
               CASE 
                 WHEN Trim(trans_type) = 'credit' THEN ball = 
                 Trim(bal) + Trim(amt) 
                 ELSE ball = Trim(bal) - Trim(amt) 
               end 
        FROM   ban) l; 
4

6 回答 6

4

这个查询可以解决问题:

SELECT t1.cust_id,t1.acc_no,t1.trans_id,t1.trans_type,t1.amount,
       sum(t2.amount*case when t2.trans_type = 'credit' then 1 
                             else -1 end) as balance
FROM Table1 t1
INNER JOIN Table1 t2 ON t1.cust_id = t2.cust_id AND 
                        t1.acc_no = t2.acc_no AND 
                        t1.trans_id >= t2.trans_id
GROUP BY t1.cust_id,t1.acc_no,t1.trans_id,t1.trans_type,t1.amount

请参阅 SQLFIDDLE:http ://www.sqlfiddle.com/#!2/3b5d8/15/0

编辑: SQL小提琴

MySQL 5.5.32 架构设置

CREATE TABLE Table1
    (`cust_id` int, `acc_no` int, `trans_id` int, 
     `trans_type` varchar(6), `amount` int)
;

INSERT INTO Table1
    (`cust_id`, `acc_no`, `trans_id`, `trans_type`, `amount`)
VALUES
    (1111, 1001, 10, 'credit', 2000.0),
    (1111, 1001, 11, 'credit', 1000.0),
    (1111, 1001, 12, 'debit', 1000.0),
    (2222, 1002, 13, 'credit', 2000.0),
    (2222, 1002, 14, 'debit', 1000.0)
;

查询 1

SELECT t1.cust_id,t1.acc_no,t1.trans_id,t1.trans_type,t1.amount,
       sum(t2.amount*case when t2.trans_type = 'credit' then 1 
                             else -1 end) as balance
FROM Table1 t1
INNER JOIN Table1 t2 ON t1.cust_id = t2.cust_id AND 
                        t1.acc_no = t2.acc_no AND 
                        t1.trans_id >= t2.trans_id
GROUP BY t1.cust_id,t1.acc_no,t1.trans_id,t1.trans_type,t1.amount

结果

| CUST_ID | ACC_NO | TRANS_ID | TRANS_TYPE | AMOUNT | BALANCE |
|---------|--------|----------|------------|--------|---------|
|    1111 |   1001 |       10 |     credit |   2000 |    2000 |
|    1111 |   1001 |       11 |     credit |   1000 |    3000 |
|    1111 |   1001 |       12 |      debit |   1000 |    2000 |
|    2222 |   1002 |       13 |     credit |   2000 |    2000 |
|    2222 |   1002 |       14 |      debit |   1000 |    1000 |
于 2013-08-28T17:58:00.983 回答
0

您可以通过 a 轻松完成此操作View,可以直接在表上进行计算,但会导致性能和可伸缩性问题(数据库将随着表的增长而变慢)。通过使用 aView按需进行计算;如果您为视图编制索引,则可以使余额保持最新,而不会影响事务表的性能。

如果您真的坚持将其放在交易表本身中,您可能会使用计算列来运行用户定义的函数来确定当前余额。但是,这在很大程度上取决于您使用的特定 SQL 后端。


这是一个基本的 SELECT 语句,它按帐户计算当前余额:

select
acc_no, 
sum(case trans_type 
    when 'credit' then amount 
    when 'debit' then amount * -1 
    end) as Amount 
from Transactions
group by acc_no
于 2013-08-28T17:40:22.020 回答
0

一个简单的解决方案是根据 trans_type 量化每个事务(- 或 +),然后使用窗口函数获得累积和。

SELECT cust_id, 
   acc_no, 
   trans_id, 
   trans_type, 
   amount, 
   Sum (real_amount) 
     OVER (ORDER BY cust_id) AS balance 
FROM   (SELECT cust_id, 
           acc_no, 
           trans_id, 
           trans_type, 
           amount, 
           ( CASE trans_type 
               WHEN 'credit' THEN amount 
               WHEN 'debit' THEN amount *- 1 
             END ) AS real_amount 
    FROM   test) t
于 2020-10-22T07:08:26.807 回答
0

您可以使用窗口功能:

select cust_id, 
acc_no, trans_id, trans_type, amount, 
sum(pre_balance) over (partition by cust_id order by trans_id) as balance
from    
(select cust_id, acc_no, trans_id, trans_type, 
        amount, 
        amount as pre_balance from test 
        where trans_type = 'credit' 
 union
 select cust_id, acc_no, trans_id, trans_type, 
        amount, -amount as pre_balance from 
        test where trans_type = 'debit'
 order by trans_id) as sub;
于 2018-01-03T08:42:23.387 回答
0
表(交易) - “id” “amount” “is_credit”

1 10000 1
2 2000 0
3 5000 1

询问 :

SELECT * FROM ( SELECT id, amount, SUM(CASE When is_credit=1 Then amount Else -amount End) OVER (ORDER BY id) AS balance FROM `Transaction` GROUP BY id, amount ) ORDER BY id ;

输出 :

“id” “金额” “is_credit” “余额”

1 10000 1 10000

2 2000 0 8000

3 5000 1 13000

于 2021-05-07T03:02:23.570 回答
0
with current_balances as (
SELECT
       id,
       user_id,
       SUM(amount) OVER (PARTITION BY user_id ORDER BY created ASC) as current_balance
FROM payments_transaction pt
ORDER BY created DESC
)
SELECT
    pt.id,
    amount,
    pt.user_id,
    cb.current_balance as running_balance
FROM
    payments_transaction pt
INNER JOIN
    current_balances cb
ON pt.id = cb.id
ORDER BY created DESC
LIMIT 10;

这将非常有效地获得大回报,并且不会因过滤或限制而中断。请注意,如果您只选择一个用户或其中的一个子集,请在cte 和主选择中提供user_id过滤器以省略整个表扫描。current_balances

于 2020-04-10T08:47:16.637 回答