En supposant que je comprenne correctement votre exigence, voici une méthode qui utilise la méthode Tabibitosan pour "grouper" les données en fonction d'ids de transaction nuls/non nuls consécutifs. Une fois que nous avons ces informations, nous pouvons alors faire un row_number() conditionnel selon que le transaction_id est nul ou non.
WITH sample_data AS (SELECT 253442 Invoice_Id, 23334 Customer_id, NULL Transaction_id, 1 seq FROM dual UNION ALL
SELECT 253443 Invoice_Id, 23334 Customer_id, NULL Transaction_id, 2 seq FROM dual UNION ALL
SELECT 253444 Invoice_Id, 23334 Customer_id, NULL Transaction_id, 3 seq FROM dual UNION ALL
SELECT 253445 Invoice_Id, 23334 Customer_id, 123 Transaction_id, 4 seq FROM dual UNION ALL
SELECT 1050646 Invoice_Id, 23334 Customer_id, 456 Transaction_id, 5 seq FROM dual UNION ALL
SELECT 8457065 Invoice_Id, 23334 Customer_id, 789 Transaction_id, 6 seq FROM dual UNION ALL
SELECT 9052920 Invoice_Id, 23334 Customer_id, NULL Transaction_id, 7 seq FROM dual UNION ALL
SELECT 9333044 Invoice_Id, 23334 Customer_id, NULL Transaction_id, 8 seq FROM dual UNION ALL
SELECT 9616743 Invoice_Id, 23334 Customer_id, NULL Transaction_id, 9 seq FROM dual UNION ALL
SELECT 9894491 Invoice_Id, 23334 Customer_id, NULL Transaction_id, 10 seq FROM dual UNION ALL
SELECT 10186697 Invoice_Id, 23334 Customer_id, NULL Transaction_id, 11 seq FROM dual UNION ALL
SELECT 10490938 Invoice_Id, 23334 Customer_id, NULL Transaction_id, 12 seq FROM dual UNION ALL
SELECT 10803986 Invoice_Id, 23334 Customer_id, 69709477 Transaction_id, 13 seq FROM dual UNION ALL
SELECT 11132317 Invoice_Id, 23334 Customer_id, 72103163 Transaction_id, 14 seq FROM dual UNION ALL
SELECT 11444923 Invoice_Id, 23334 Customer_id, NULL Transaction_id, 15 seq FROM dual)
-- end of mimicking your data in a "table" called sample_data
-- you wouldn't need this - you'd just select from your table directly in the sql below:
SELECT invoice_id,
customer_id,
transaction_id,
seq,
CASE WHEN transaction_id is not NULL THEN
row_number() OVER (PARTITION BY customer_id, grp ORDER BY seq)
ELSE 0
END carryover
FROM (SELECT invoice_id,
customer_id,
transaction_id,
seq,
row_number() OVER (PARTITION BY customer_id ORDER BY seq)
- row_number() OVER (PARTITION BY customer_id, CASE WHEN transaction_id IS NULL THEN 0 ELSE 1 END ORDER BY seq) grp
FROM sample_data)
ORDER BY customer_id, seq;
INVOICE_ID CUSTOMER_ID TRANSACTION_ID SEQ CARRYOVER
---------- ----------- -------------- ---------- ----------
253442 23334 1 0
253443 23334 2 0
253444 23334 3 0
253445 23334 123 4 1
1050646 23334 456 5 2
8457065 23334 789 6 3
9052920 23334 7 0
9333044 23334 8 0
9616743 23334 9 0
9894491 23334 10 0
10186697 23334 11 0
10490938 23334 12 0
10803986 23334 69709477 13 1
11132317 23334 72103163 14 2
11444923 23334 15 0
Pour l'exigence supplémentaire :
WITH sample_data AS (SELECT 253442 Invoice_Id, 23334 Customer_id, 0 Transaction_Count, 1 seq FROM dual UNION ALL
SELECT 253443 Invoice_Id, 23334 Customer_id, 0 Transaction_Count, 2 seq FROM dual UNION ALL
SELECT 253444 Invoice_Id, 23334 Customer_id, 1 Transaction_Count, 3 seq FROM dual UNION ALL
SELECT 253445 Invoice_Id, 23334 Customer_id, 1 Transaction_Count, 4 seq FROM dual UNION ALL
SELECT 1050646 Invoice_Id, 23334 Customer_id, 0 Transaction_Count, 5 seq FROM dual UNION ALL
SELECT 8457065 Invoice_Id, 23334 Customer_id, 0 Transaction_Count, 6 seq FROM dual UNION ALL
SELECT 9052920 Invoice_Id, 23334 Customer_id, 2 Transaction_Count, 7 seq FROM dual UNION ALL
SELECT 9333044 Invoice_Id, 23334 Customer_id, 1 Transaction_Count, 8 seq FROM dual UNION ALL
SELECT 9616743 Invoice_Id, 23334 Customer_id, 0 Transaction_Count, 9 seq FROM dual UNION ALL
SELECT 9894491 Invoice_Id, 23334 Customer_id, 0 Transaction_Count, 10 seq FROM dual UNION ALL
SELECT 10186697 Invoice_Id, 23334 Customer_id, 0 Transaction_Count, 11 seq FROM dual UNION ALL
SELECT 10490938 Invoice_Id, 23334 Customer_id, 0 Transaction_Count, 12 seq FROM dual UNION ALL
SELECT 10803986 Invoice_Id, 23334 Customer_id, 1 Transaction_Count, 13 seq FROM dual UNION ALL
SELECT 11132317 Invoice_Id, 23334 Customer_id, 1 Transaction_Count, 14 seq FROM dual UNION ALL
SELECT 11444923 Invoice_Id, 23334 Customer_id, 0 Transaction_Count, 15 seq FROM dual)
-- end of mimicking your data in a "table" called sample_data
-- you wouldn't need this - you'd just select from your table directly in the sql below:
SELECT invoice_id,
customer_id,
Transaction_Count,
seq,
SUM(transaction_count) OVER (PARTITION BY customer_id,
CASE WHEN Transaction_Count = 0 THEN 0 ELSE 1 END,
grp
ORDER BY seq) carryover
FROM (SELECT invoice_id,
customer_id,
Transaction_Count,
seq,
row_number() OVER (PARTITION BY customer_id
ORDER BY seq)
- row_number() OVER (PARTITION BY customer_id,
CASE WHEN Transaction_Count = 0 THEN 0 ELSE 1 END
ORDER BY seq) grp
FROM sample_data)
ORDER BY customer_id, seq;
INVOICE_ID CUSTOMER_ID TRANSACTION_COUNT SEQ CARRYOVER
---------- ----------- ----------------- ---------- ----------
253442 23334 0 1 0
253443 23334 0 2 0
253444 23334 1 3 1
253445 23334 1 4 2
1050646 23334 0 5 0
8457065 23334 0 6 0
9052920 23334 2 7 2
9333044 23334 1 8 3
9616743 23334 0 9 0
9894491 23334 0 10 0
10186697 23334 0 11 0
10490938 23334 0 12 0
10803986 23334 1 13 1
11132317 23334 1 14 2
11444923 23334 0 15 0
Il utilise un concept très similaire à la solution d'origine, sauf qu'en ajoutant la vérification de zéro ou non zéro transaction_count dans la clause partition by de la fonction analytique sum() finale, nous n'avons plus besoin de l'instruction case pour sortir 0 ou la somme .
J'espère que vous pouvez dire quels ajustements j'ai dû faire - en gros, les vérifications pour transaction_id est null/not null ont dû être changées en transaction_count =0/!=0, plus le changement de row_number()
à sum(transaction_count)
plus la modification précitée de la clause de partage. Je suis sûr que si vous y aviez réfléchi un peu plus, vous seriez arrivé à la même conclusion, si vous ne l'avez pas déjà fait ! *{:-)