Oracle:根据同一表

时间:2018-02-08 13:25:07

标签: sql oracle group-by sql-order-by

我有一个表error_event_table,有3列:

eventtime timestamp;
url varchar2(1024);
errorcount number(30);

该表有超过300万个数据,我需要根据给定开始时间和结束时间的errorcount列值的差异找到前n(100)个URL。 例如:表数据如下

eventtime           | url      |errorcount
2018-01-29 10:20:00 | url1.com | 950
2018-01-29 10:25:00 | url1.com | 1000
2018-01-29 10:20:00 | url2.com | 100
2018-01-29 10:25:00 | url2.com | 400
2018-01-29 10:25:00 | url3.com | 500
2018-01-29 10:10:00 | url35.com | 500

当startTime = 2018-01-29 10:20:00和endTime = 2018-01-29 10:25:00作为输入传递给查询时,预期输出为:

eventtime           | url      |errorcount

2018-01-29 10:25:00 | url3.com | 500
2018-01-29 10:25:00 | url2.com | 400
2018-01-29 10:20:00 | url2.com | 100
2018-01-29 10:25:00 | url1.com | 1000
2018-01-29 10:20:00 | url1.com | 950

查询应根据给定开始时间和结束时间(查询输入)的errorcount数量差异对记录进行排序,并将结果限制为前100位。以其他方式说,查询应该找到顶部100个URL在结束时间和开始时间具有最大差异,并在开始时间和结束时间生成相应的URL记录。

URL可能仅在结束时而不是在开始时存在,在这种情况下,开始时间errorcount应该被视为0.类似地,URL可能仅在开始时存在,在这种情况下diff将为负数字,我不希望在我的结果中使用这些-ve diff记录。

我尝试了两种方法,但没有能够采用适当的方法来进行更进一步的工作。

方法1:使用分组依据

SELECT url, 
       Max(eventtime), 
       Max(errorcount) 
FROM   error_event_table 
WHERE  eventtime IN ( To_date(:startTime, 'yyyymmddHH24MISS'), 
                      To_date(:endTime, 'yyyymmddHH24MISS') 
                           ) 
GROUP  BY url 
ORDER  BY Max(errorcount)DESC; 

Approch 2:使用自我加入

SELECT t2.url                            eurl, 
       t1.url                            surl, 
       t2.eventtime                      endtime, 
       t1.eventtime                      starttime, 
       ( t2.errorcount - t1.errorcount ) diff 
FROM   error_event_table t1, 
       error_event_table t2 
WHERE  ( t1.eventtime = To_date(:startTime, 'yyyymmddHH24MISS') 
          OR t2.eventtime = To_date(:endTime, 'yyyymmddHH24MISS') ) 
       AND t2.url (+) = t1.url 
ORDER  BY ( t2.errorcount - t1.errorcount ) DESC 

请提供有关如何解决此问题的方法的输入。

1 个答案:

答案 0 :(得分:0)

如果我理解正确,您想使用lag()

select t.*,
       (error_count - 
        lag(error_count, 1, 0) over (partition by url order by eventtime)
       ) as diff
from t
where <date conditions here>
order by diff desc;

编辑:

如果您只想要具有最大值的网址,则:

select t.*
from (select t.*, row_number() over (partition by url order by diff desc) as seqnum
      from (select t.*,
                   (error_count - 
                    lag(error_count, 1, 0) over (partition by url order by eventtime)
                   ) as diff
            from t
            where <date conditions here>
           ) t
     ) t
where seqnum <= 100
order by diff desc;