2014-03-13 52 views
0

我有一個名爲project_errors表具有列project_idtotal_errorsdate。因此,每天都會運行一個批處理作業,在特定日期爲特定項目插入包含錯誤數量的行。差異在同一列的Oracle表

現在我想知道有多少誤差減小,有多少錯誤被引入了一個項目一個給定的月份。我想到了插入後創建觸發器的解決方案,它將記錄錯誤是增加還是減少並放到另一個表中。但是這對先前插入的數據不起作用。有沒有其他辦法可以做到這一點?我研究了滯後函數,但不知道如何爲我的問題做到這一點。表結構如下。

Project_Id  Total_Errors  Row_Insert_Date 
    1     56    08-MAR-14 
    2     14    08-MAR-14 
    3     89    08-MAR-14 
    1     54    07-MAR-14 
    2     7     07-MAR-14 
    3     80    07-MAR-14 

等等......

+0

正是你想要在新列看什麼? – SriniV

回答

3

它總是有益的,如果你能證明你想要的輸出。我的猜測是,你想從56減去54,並表明項目1加2個錯誤,從14減7顯示,項目2加7級的錯誤,並從89減去80表明下添加9個錯誤項目3.假設是這樣的話

SELECT project_id, 
     total_errors, 
     lag(total_errors) over(partition by project_id 
            order by row_insert_date) prior_num_errors, 
     total_errors - 
     lag(total_errors) over(partition by project_id 
             order by row_insert_date) difference 
    FROM table_name 

,如果你想在prior_num_errors到的第一天0您可能需要拋出LAG圍繞NVL

+0

+1我有片段和結果,但你是快槍。我可以在這裏粘貼嗎? – SriniV

0

積分賈斯汀。只是想到了粘貼結果。

WITH TEMP 
    AS (SELECT 1 AS PROJECT_ID, 
       56 AS TOTAL_ERRORS, 
       '08-MAR-14' AS ROW_INSERT_DATE 
     FROM DUAL 
     UNION ALL 
     SELECT 2 AS PROJECT_ID, 
       14 AS TOTAL_ERRORS, 
       '08-MAR-14' AS ROW_INSERT_DATE 
     FROM DUAL 
     UNION ALL 
     SELECT 3 AS PROJECT_ID, 
       89 AS TOTAL_ERRORS, 
       '08-MAR-14' AS ROW_INSERT_DATE 
     FROM DUAL 
     UNION ALL 
     SELECT 1 AS PROJECT_ID, 
       54 AS TOTAL_ERRORS, 
       '07-MAR-14' AS ROW_INSERT_DATE 
     FROM DUAL 
     UNION ALL 
     SELECT 2 AS PROJECT_ID, 
       7 AS TOTAL_ERRORS, 
       '07-MAR-14' AS ROW_INSERT_DATE 
     FROM DUAL 
     UNION ALL 
     SELECT 3 AS PROJECT_ID, 
       80 AS TOTAL_ERRORS, 
       '07-MAR-14' AS ROW_INSERT_DATE 
     FROM DUAL) 
SELECT PROJECT_ID, 
     TOTAL_ERRORS, 
     NVL (
       TOTAL_ERRORS 
      - LAG (TOTAL_ERRORS) 
        OVER (PARTITION BY PROJECT_ID ORDER BY ROW_INSERT_DATE), 
      0) 
      CHANGES, 
     ROW_INSERT_DATE 
FROM TEMP; 

PROJECT_ID TOTAL_ERRORS CHANGES ROW_INSERT_DATE 
---------- ------------ ---------- --------------- 
     1   54   0 07-MAR-14  
     1   56   2 08-MAR-14  
     2   7   0 07-MAR-14  
     2   14   7 08-MAR-14  
     3   80   0 07-MAR-14  
     3   89   9 08-MAR-14  

6 rows selected. 
1

除了賈斯丁的回答,你可能要考慮改變你的表格結構。您可以記錄實際的錯誤,然後對它們進行計數,而不是僅記錄總計。

因此,假設你有一個像表結構:

CREATE TABLE PROJECT_ERRORS(
    project_id INTEGER 
    error_id INTEGER 
    stamp DATETIME 
) 

每個記錄將是一個單獨的錯誤(或單獨的錯誤類型),這會給你更多的粒度和允許更復雜的查詢。
您仍然可以通過一天,讓你的總數:

SELECT project_id, COUNT(error_id), TO_CHAR(stamp, 'DD-MON-YY') AS EACH_DAY 
FROM PROJECT_ERRORS 
GROUP BY project_id, TO_CHAR(stamp, 'DD-MON-YY') 

如果我們結合這跟JUSTIN'S真棒答案:

SELECT 
    project_id          AS PROJECT_ID, 
    COUNT(error_id)         AS TOTAL_ERRORS, 
    LAG(COUNT(error_id)) 
      OVER(PARTITION BY project_id 
      ORDER BY TO_CHAR(stamp, 'DD-MON-YY')) AS prior_num_errors, 
    COUNT(error_id) - LAG(COUNT(error_id)) 
      OVER(PARTITION BY project_id 
      ORDER BY TO_CHAR(stamp, 'DD-MON-YY')) AS diff 
FROM project_errors 
GROUP BY 
    project_id, 
    TO_CHAR(stamp, 'DD-MON-YY') 

但現在你也可以幻想和尋找特定類型的錯誤或在一天中的某些時段觀看。