2016-10-25 72 views
1

我有一張持有客戶發票數據的表格。我試圖通過創建一個結轉計數器來查找客戶的發票上有多少個月特定的交易類型。如果交易不再存在,計數器應重置爲零。甲骨文 - 增量值

表:

+------------+-------------+----------------+----------+ 
| 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 | 
+------------+-------------+----------------+----------+-----------+ 

我以爲我可以使用分析功能/ Oracle的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, 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 

對於附加要求:

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檢查到由子句分區最後的sum()分析函數中,我們不再需要case語句來輸出0或總和。

希望你能告訴我有什麼調整,以使 - 基本上,對於TRANSACTION_ID支票爲空/不爲空,就必須改變以transaction_count = 0/= 0,加row_number()sum(transaction_count)的變化,加上前面提到的改變!到分區的條款。我敢肯定,如果你還有更多的想法,如果還沒有的話,你會得出同樣的結論! * {:-)

+0

謝謝你的出色答案。假設每個發票的transaction_id被替換爲非空的transaction_count。結轉將代替從1開始,從transaction_count開始。隨後將結轉計算爲transaction_count上一行+交易計數當前行。事務計數中的0將像以前一樣將殘留重置爲0.這是否可以通過使用LAG分析函數來實現? – MrM

+0

我不確定我明白你的意思。請更新您問題中的示例數據和預期輸出以說明您的意思。從表面上看,我認爲你只需要一個'sum()'來代替'row_number()'來做一個累計和。但是,如果沒有看到數據的外觀以及預期的輸出結果,很難說是否如此。 – Boneist

+0

沒有給出預期的結果。上面更新的初始問題。 – MrM