Найти сумму суммы для конкретного типа сделки за 2 дня подряд - PullRequest
0 голосов
/ 25 марта 2019

У меня есть две таблицы 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

Я должен найти соотношение суммы суммы для двух последовательных дней аналогичного типа транзакции для того же ключа счета.например, (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 голосов
/ 26 марта 2019

Вы можете использовать предложение 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;
0 голосов
/ 26 марта 2019

Я бы попробовал использовать для временных таблиц.Сохраните суммы каждого типа транзакции в двух временных таблицах, а затем используйте их для расчета вашего коэффициента.Я не проверял этот запрос, но это в основном то, что вы ищете:

 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

Конечно, в зависимости от ваших потребностей, вам нужно будет указать начальную дату

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...