2016-10-25 4 views
1

고객 송장 데이터가있는 테이블이 있습니다. 캐리 오버 카운터를 생성하여 고객의 인보이스에 특정 거래 유형이 얼마나 많이 있는지 찾기 위해 노력하고 있습니다. 거래가 더 이상 존재하지 않으면 카운터는 0으로 재설정해야합니다.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의

누적 합계 때 Tabibitosan method에 "그룹의"사용 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

내가 제대로 귀하의 요구 사항을 이해 가정하면, 여기에 한 가지 방법, onsecutive null/not-null transaction_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 

그것은 PARTITION BY 절에 제로 또는 비 - 제로 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에 대한 검사/NOT NULL = 0/= 0, 플러스 sum(transaction_count)row_number()의 변화 플러스 전술 변화를 transaction_count 변경해야했다 null 인 -

희망 당신은 내가해야했다 무엇을 개조하면 되겠 어 말할 수있다 partition by 절에. 만약 당신이 아직 그것에 대해 생각해 본 적이 없다면, 같은 결론에 도달했을 것입니다. * {:-)

+0

훌륭한 답변을 보내 주셔서 감사합니다. 송장 당 transaction_id가 not-null transaction_count로 대체되었다고 가정합니다. 이월은 1로 시작하는 대신 transaction_count로 시작합니다. 이월은 transaction_count 이전 행 + 트랜잭션 카운트 현재 행으로 계산됩니다. 트랜잭션 수의 0은 이전과 같이 carryover를 0으로 재설정합니다. 이는 LAG 분석 함수를 사용하여 달성 할 수 있습니까? – MrM

+0

나는 당신이 의미하는 것을 얻을지 확신하지 못합니다. 귀하의 질문에 샘플 데이터와 예상 결과를 업데이트하여 귀하의 의미를 입증하십시오. 그것의 얼굴에, 당신은 단지 누적 합계를하기 위해'row_number()'대신에'sum()'이 필요할 것이라고 생각합니다. 그러나 예상되는 출력뿐만 아니라 데이터가 어떻게 보이는지 보지 않고도 그런 경우인지를 말하기는 어렵습니다. – Boneist

+0

는 예상 된 결과를 제공하지 못했습니다. 초기 질문이 위에 업데이트되었습니다. – MrM