选择条目窗口

时间:2012-02-28 20:01:53

标签: sql oracle oracle11g

考虑以下(简称)表:

ID           NUMBER
PROD_NO      VARCHAR2(10)
START_TIME   DATE

我想要做的是在给定的START_TIME周围选择一个大小为n的行的“窗口”。

示例:

ID   PROD_NO   START_TIME
...
42   1234567   2012-02-28 13:42:10
43   1234568   2012-02-28 13:47:53
44   1234569   2012-02-28 13:52:22
45   1234570   2012-02-28 13:59:01
46   1234571   2012-02-28 14:02:12
47   1234572   2012-02-28 14:05:19
... 

如果START_TIME ='2012-02-28 14:00:00'且窗口大小n = 4,则生成的行集应为ID 44 ... 47。

不能假设条目按START_TIME排序。如果没有足够的条目可用于匹配指定的窗口大小,则可以裁剪它。

由于我的SQL技能非常有限,任何帮助都会受到高度赞赏。

提前致谢。

2 个答案:

答案 0 :(得分:5)

您可以使用分析函数来帮助解决此问题:

select WT.ID
  from (select WT.ID
              ,max(
                 START_TIME)
               over (order by START_TIME
                     rows between 2 preceding and 2 following)
                 as MAXST
              ,min(
                 START_TIME)
               over (order by START_TIME
                     rows between 2 preceding and 2 following)
                 as MINST
          from WT) WT
 where MINST < to_date('2012-02-28 14:00:00', 'yyyy-mm-dd hh24:mi:ss')
       and MAXST > to_date('2012-02-28 14:00:00', 'yyyy-mm-dd hh24:mi:ss')

答案 1 :(得分:3)

现在应该可以了:

SELECT *
FROM   (SELECT id, 
               prod_no, 
               start_time, 
               ROWNUM rn,
               datediff
        FROM   (SELECT   id,
                         prod_no,
                         start_time,
                         start_time
                         - TO_DATE('01-JAN-2011 12:00:00',
                                   'DD-MON-YYYY HH:MI:SS AM')
                            datediff
                FROM     table
                WHERE    start_time
                         - TO_DATE('01-JAN-2011 12:00:00',
                                   'DD-MON-YYYY HH:MI:SS AM') > 0
                ORDER BY datediff))
WHERE  rn <= 2
UNION ALL
SELECT *
FROM   (SELECT id, 
               prod_no, 
               start_time, 
               ROWNUM rn,
               datediff
        FROM   (SELECT   id,
                         prod_no,
                         start_time,
                         start_time
                         - TO_DATE('01-JAN-2011 12:00:00',
                                   'DD-MON-YYYY HH:MI:SS AM')
                            datediff
                FROM     table
                WHERE    start_time
                         - TO_DATE('01-JAN-2011 12:00:00',
                                   'DD-MON-YYYY HH:MI:SS AM') <= 0
                ORDER BY datediff DESC))
WHERE  rn <= 2