2016-10-25 9 views
1

私は顧客請求書データを保持するテーブルを持っています。私はキャリーオーバー・カウンターを作成することによって、顧客の請求書に特定の取引タイプが何ヶ月続くかを調べようとしています。トランザクションが存在しなくなると、カウンタはゼロにリセットされます。Oracle - 増分値

表:私が達成しようとしています何

+------------+-------------+----------------+----------+ 
| Invoice_Id | Customer_id | Transaction_id | Sequence | 
+------------+-------------+----------------+----------+ 
|  253442 |  23334 |    |  1 | 
|  253443 |  23334 |    |  2 | 
|  253444 |  23334 |    |  3 | 
|  253445 |  23334 |    |  4 | 
| 1050646 |  23334 |    |  5 | 
| 8457065 |  23334 |    |  6 | 
| 9052920 |  23334 |    |  7 | 
| 9333044 |  23334 |    |  8 | 
| 9616743 |  23334 |    |  9 | 
| 9894491 |  23334 |    |  10 | 
| 10186697 |  23334 |    |  11 | 
| 10490938 |  23334 |    |  12 | 
| 10803986 |  23334 |  69709477 |  13 | 
| 11132317 |  23334 |  72103163 |  14 | 
| 11444923 |  23334 |    |  15 | 
+------------+-------------+----------------+----------+ 

+------------+-------------+----------------+----------+-----------+ 
| Invoice_Id | Customer_id | Transaction_id | Sequence | Carryover | 
+------------+-------------+----------------+----------+-----------+ 
|  253442 |  23334 |    |  1 |   0 | 
|  253443 |  23334 |    |  2 |   0 | 
|  253444 |  23334 |    |  3 |   0 | 
|  253445 |  23334 |    |  4 |   0 | 
| 1050646 |  23334 |    |  5 |   0 | 
| 8457065 |  23334 |    |  6 |   0 | 
| 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 | 
+------------+-------------+----------------+----------+-----------+ 

私は分析関数/オラクルのCTEを使用することができますと仮定?

ありがとうございます!

追加:リセットとtransaction_count値の

累積和transaction_count値= 0

+------------+-------------+-------------------+----------+-----------+ 
| Invoice_Id | Customer_id | Transaction_Count | Sequence | 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 | 
+------------+-------------+-------------------+----------+-----------+ 

答えて

1

は、私はあなたの要件が正しく、ここでは「グループ」にTabibitosan methodを使用しています一つの方法は、だ理解と仮定すると、 onsecutive null/not-null tr​​ansaction_idsに基づくデータ。その情報を取得したら、transaction_idがnullかどうかに基づいて条件付きrow_number()を実行できます。

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 

それは句によってパーティションにゼロまたは非ゼロtransaction_count値のチェックを追加することにより除き、元の溶液と非常に似た概念を使用する:追加の要件について

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 

最終的なsum()解析関数のうち、0またはその和を出力するためにcase文は必要なくなりました。

うまくいけば、あなたは私がしなければならなかったものを微調整伝えることができます! - 基本的には、TRANSACTION_IDのためのチェックが= 0/= 0、プラスsum(transaction_count)row_number()の変更に加えて、前述の変更をtransaction_count値に変更しなければならなかったヌル/ nullではありませんpartition by節に追加します。もしあなたがまだそれを考えていなければ、あなたは同じ結論に来たでしょう! * {:-)

+0

すばらしい答えをありがとう。 invoiceごとにtransaction_idがnot-null tr​​ansaction_countに置き換えられていると仮定します。繰り越しは1で始まるのではなく、transaction_countで始まります。キャリーオーバーは、transaction_count前行+トランザクションカウント現在行として計算されます。トランザクション数の0は、キャリーオーバーを0にリセットする前と同じです。これは、LAG分析関数を使用して達成可能ですか? – MrM

+0

私はあなたが何を意味するか分かりません。あなたが意味するものを実証するために、あなたの質問のサンプルデータと予想される結果を更新してください。その面では、 'row_number()'の代わりに 'sum()'が必要だと思います。しかし、データがどのように見えるのか、期待される出力を見ることなく、そうであるかどうかは分かりません。 – Boneist

+0

は期待された結果を得ていませんでした。上記の最初の質問が更新されました。 – MrM