2014-03-13 55 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') 

但现在你也可以幻想和寻找特定类型的错误或在一天中的某些时段观看。