我有两个表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
答案 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版本,您可能需要避免使用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
根据您的需求,当然,您必须声明开始日期