连续2天找出特定交易类型的金额总和

时间:2019-03-25 20:21:54

标签: sql oracle

我有两个表1.交易和2.交易类型

例如带有伪数据的交易表的显示

account_key  Transaction_key    date        amount
1                 11          03/22/0219     5000
1                 12          03/23/2019     6000
1                 13          03/22/2019     4000
1                 14          03/23/2019     3000

例如带有虚假数据的Transaction_type表

transaction_key    transaction_type
11                      in
12                      in
13                      out
14                      out

我必须找到同一帐户密钥的相似交易类型的连续2天的金额之和。例如(5000 + 6000)/(4000 + 3000)

数据库为oracle,数据类型为datetime

这是我尝试过的

select t1.account_key,
       trunc(t1.date),
       sum(t1.amount) as in,
       sum(t2.amount) as out
from   transactions t1 
inner join transactions t2 on t1.accountkey=t2.accountkey
where t1.date between '01-jun-2017' and '30-nov-2017' 
and   t2.date between '01-jun-2017' and '30-nov-2017'
and   t1.transaction_key in (select a.transaction_key 
                             from   transaction_type a
                             where  a.transaction type in 'in')
and   t2.transaction_key in (select b.transaction_key 
                             from   transaction_type b
                             where  b.transaction type in 'out') 
group by t1.account_key,
         trunc(t1.date)
having   max(trunc(t1.date))-min(trunc(t1.date)) = 1
and      max(trunc(t2.date))-min(trunc(t2.date)) = 1

2 个答案:

答案 0 :(得分:0)

您可以使用WITH子句(也称为“公用表表达式”或“ CTE”)将问题分解为可管理的块。

这是一种实现方法:

WITH txn_by_date AS ( 
  SELECT t.account_key, 
         t.txn_date, 
         tt.transaction_type, 
         sum(t.amount) amount
  FROM   txns t 
  INNER JOIN txn_types tt on tt.transaction_key = t.transaction_key 
  GROUP BY t.account_key, t.txn_date, tt.transaction_type )
SELECT tin.account_key, 
       tin.txn_date, 
       tin.amount amount_in,
       tout.txn_date, 
       tout.amount amount_out,
       tin.amount / tout.amount ratio
FROM   txn_by_date tin
INNER JOIN txn_by_date tout ON tout.txn_date = tin.txn_date + 1 
                           AND tout.transaction_type = 'out'
                           AND tout.account_key = tin.account_key
WHERE tin.transaction_type = 'in';

CTE首先按帐户,交易类型和日期计算总txn金额。一旦有了,主SELECT就会获得每个“入”总数,并将其与连续一天的“出”总数相加,然后计算比率。

这是一个完整的示例,其中包含测试数据(也使用WITH子句表示):

with txns (account_key,  Transaction_key,    txn_date,    amount) AS
( 
SELECT 1, 11, TO_DATE('03/22/2019','MM/DD/YYYY'), 5000 FROM DUAL UNION ALL
SELECT 1, 12, TO_DATE('03/23/2019','MM/DD/YYYY'), 6000 FROM DUAL UNION ALL
SELECT 1, 13, TO_DATE('03/22/2019','MM/DD/YYYY'), 4000 FROM DUAL UNION ALL
SELECT 1, 14, TO_DATE('03/23/2019','MM/DD/YYYY'), 3000 FROM DUAL ),
txn_types ( transaction_key, transaction_type ) AS 
( 
SELECT 11, 'in' FROM DUAL UNION ALL
SELECT 12, 'out' FROM DUAL UNION ALL
SELECT 13, 'in' FROM DUAL UNION ALL
SELECT 14, 'out' FROM DUAL ),
txn_by_date AS ( 
  SELECT t.account_key, 
         t.txn_date, 
         tt.transaction_type, 
         sum(t.amount) amount
  FROM   txns t 
  INNER JOIN txn_types tt on tt.transaction_key = t.transaction_key 
  GROUP BY t.account_key, t.txn_date, tt.transaction_type )
SELECT tin.account_key, 
       tin.txn_date, 
       tin.amount amount_in,
       tout.txn_date, 
       tout.amount amount_out,
       tin.amount / tout.amount ratio
FROM   txn_by_date tin
INNER JOIN txn_by_date tout ON tout.txn_date = tin.txn_date + 1 
                           AND tout.transaction_type = 'out'
                           AND tout.account_key = tin.account_key
WHERE tin.transaction_type = 'in';
+-------------+-----------+-----------+------------+------------+-------+
| ACCOUNT_KEY | TXN_DATE  | AMOUNT_IN | TXN_DATE_1 | AMOUNT_OUT | RATIO |
+-------------+-----------+-----------+------------+------------+-------+
|           1 | 22-MAR-19 |      9000 | 23-MAR-19  |       9000 |     1 |
+-------------+-----------+-----------+------------+------------+-------+

替代版本,有关Oracle的古代版本

对于真正旧的Oracle版本,您可能需要避免使用WITH子句和ANSI样式的连接。这是上面为避免这些功能而重写的查询。

SELECT tin.account_key, 
       tin.txn_date, 
       tin.amount amount_in,
       tout.txn_date, 
       tout.amount amount_out,
       tin.amount / tout.amount ratio
FROM   ( SELECT t.account_key, 
                t.txn_date, 
                tt.transaction_type, 
                sum(t.amount) amount
         FROM   txns t,
                txn_types tt
         WHERE  tt.transaction_key = t.transaction_key 
         GROUP BY t.account_key, t.txn_date, tt.transaction_type ) tin,
       ( SELECT t.account_key, 
                t.txn_date, 
                tt.transaction_type, 
                sum(t.amount) amount
         FROM   txns t,
                txn_types tt
         WHERE  tt.transaction_key = t.transaction_key 
         GROUP BY t.account_key, t.txn_date, tt.transaction_type ) tout
WHERE tin.transaction_type = 'in'
AND tout.transaction_type(+) = 'out'
AND tout.account_key(+) = tin.account_key;

答案 1 :(得分:-1)

我会尝试使用临时表。将每个交易类型的总和存储在两个临时表中,然后使用它们来计算比率。我尚未测试此查询,但这基本上是您要查找的内容:

 CREATE PRIVATE TEMPORARY TABLE as In_TempTable
 Select T2.Transaction_Type, sum(T1.amount) In_Total
 from Transactions T1
 left join Transaction_Type T2 on T2.Transaction_key = T1.Transaction_Key 
 where T1.date between '01-jun-2017' and '30-nov-2017'
      AND T2.Transactio_Type = 'In'
 group by T2.Transaction_Type;

 CREATE PRIVATE TEMPORARY TABLE as Out_TempTable
 Select T2.Transaction_Type, sum(T1.amount) Out_Total
 from Transactions T1
 left join Transaction_Type T2 on T2.Transaction_key = T1.Transaction_Key 
 where T1.date between '01-jun-2017' and '30-nov-2017'
      AND T2.Transactio_Type = 'Out'
 group by T2.Transaction_Type;


 Select Sum(a.In_Total)/Sum(b.Out_Total)
 from In_TempTable a
 Full Outer Join Out_TempTable b on b.Transaction_Type = a.Transaction_Type

我会亲自更改:

T1.date between '01-jun-2017' and '30-nov-2017'

像这样

T1.date between startdate and startdate+2

根据您的需求,当然,您必须声明开始日期