Нужно сгруппировать записи на основе сопоставления обращения в sql - PullRequest
0 голосов
/ 14 февраля 2020

У меня сложный сценарий для агрегирования данных.

Данные в моей исходной таблице выглядят следующим образом.

CustomerId  Transaction Type    Transaction Amount
1               Payment              100
1               ReversePayment      -100
1               payment              100
1               ReversePayment      -100
1               Payment              100
1               Payment              100

Требование следующее:

  • Если платеж как связанный обратный платеж с совпадающей суммой, суммируйте эти две записи.
  • Если платеж не связан с обратным платежом, считайте его сиротским (не суммируйте его).

Я хочу, чтобы вывод был таким.

  CustomerId    Transaction Type                Transaction Amount
   1                Payment,ReversePayment               0
   1                payment,ReversePayment               0
   1                payment                             100
   1               Payment                              100

В этом сценарии

  • Первая запись, которая является платежом, имеет связанный обратный платеж (2-я запись), следовательно, сумма становится 0
  • Третья запись, которая является платежом, имеет связанный обратный платеж (4-я запись), тогда сумма становится 0
  • Пятая и шестая не имеют связанных сторнирований. не суммируйте эти записи.

Второй пример:

Данные в источнике следующие:

 CustomerId Transaction Type    Transaction Amount
 1              Payment              100
 1              ReversePayment      -100
 1              payment              300
 1              ReversePayment      -300
 1               Payment              400
 1               Payment              500

Ожидаемый результат

CustomerId      Transaction Type                Transaction Amount
 1              Payment,ReversePayment               0
 1              payment,ReversePayment               0
 1              payment                             400
 1              Payment                             500

Второе примерное требование: -Как первая и вторая записи (платеж и связанный с ним обратный платеж были сопоставлены), суммируйте эти две записи, выходные данные равны 0. - В качестве третьей и четвертой записей (платеж и связанный с ним обратный платеж были сопоставлены), суммируйте эти два записей, вывод равен 0. - Пятый и шестой не имеет связанных разворотов. не суммируйте эти записи.

Я получил решения в группе, но данные не всегда гарантируют, что потерянные записи будут считаться «платежами». Иногда они являются «Платежами», а иногда «ReversePayments». Могут ли некоторые помочь мне получить исходный код, подобный приведенному ниже (с использованием функций ранга или числа), чтобы я мог группировать с помощью столбца RRR.

CustomerId  Transaction Type    Transaction Amount         RRR
 1              Payment              100                   1
 1              ReversePayment      -100                   1
 1              payment              100                   2
 1              ReversePayment      -100                   2
 1               Payment              100                   3
 1               Payment              100                   4


 CustomerId Transaction Type    Transaction Amount      RRR 
 1              Payment              100                 1
 1              ReversePayment      -100                 1
 1              payment              300                 2
 1              ReversePayment      -300                 2
 1               Payment              400                3
 1               Payment              500                4   

Ответы [ 2 ]

1 голос
/ 14 февраля 2020

Отредактировано, чтобы включить ваш второй сценарий:

Использование rownum для принудительного выполнения внутреннего порядка (т. Е. Транзакции происходили в указанном вами порядке), поскольку в вашем примере отсутствует идентификатор транзакции или время транзакции

    SQL> select * from trans_data2;

    CUSTOMER_ID TRANSACTION_TY TRANSACTION_AMOUNT
    ----------- -------------- ------------------
              1 Payment                       100
              1 ReversePayment               -100
              1 payment                       300
              1 ReversePayment               -300
              1 Payment                       400
              1 Payment                       500

    6 rows selected.


    SQL> select customer_id,
      2      case
      3          when upper(next_transaction) = 'REVERSEPAYMENT' then transaction_type||','||next_transaction
      4          else transaction_type
      5      end transaction_type,
      6      case
      7          when upper(next_transaction) = 'REVERSEPAYMENT' then transaction_amount + next_transaction_amount
      8          else transaction_amount
      9      end transaction_amount
     10  from (
     11      select customer_id, transaction_type, transaction_amount,
     12      lead (transaction_type) over ( partition by customer_id order by transaction_id ) next_transaction,
     13      nvl(lead (transaction_amount) over ( partition by customer_id order by transaction_id),0)  next_transaction_amount
     14      from ( select rownum transaction_id, t.* from trans_data2 t )
     15  ) where upper(transaction_type) = 'PAYMENT'
     16  ;

    CUSTOMER_ID TRANSACTION_TYPE              TRANSACTION_AMOUNT
    ----------- ----------------------------- ------------------
              1 Payment,ReversePayment                         0
              1 payment,ReversePayment                         0
              1 Payment                                      400
              1 Payment                                      500
1 голос
/ 14 февраля 2020

Вы можете перечислить различные типы и затем агрегировать:

select customerid,
       listagg(ttype, ',') within group (order by ttype) as types,
       sum(amount) as amount
from (select t.*,
             row_number() over (partition by customerid, ttype, amount order by customerid) as seqnum
      from t
     ) t
group by customerid, seqnum;
...