Oracle数据库时态查询实现 - 折叠日期范围

时间:2013-11-08 23:31:51

标签: sql oracle plsql temporal-database

这是我的一个查询的结果:

SURGERY_D
---------
01-APR-05
02-APR-05
03-APR-05
04-APR-05
05-APR-05
06-APR-05
07-APR-05

11-APR-05
12-APR-05
13-APR-05
14-APR-05
15-APR-05
16-APR-05

19-APR-05
20-APR-05
21-APR-05
22-APR-05
23-APR-05
24-APR-05

26-APR-05
27-APR-05
28-APR-05
29-APR-05
30-APR-05

我想将连续的日期范围折叠成间隔。例如,

[01-APR-05, 07-APR-05], [11-APR-05, 16-APR-05] and so on.

就时态数据库而言,我想“崩溃”日期。知道如何在Oracle上做到这一点吗?我正在使用版本11.我搜索它并阅读了一本书,但找不到/理解如何做到这一点。这可能很简单,但每个人都有自己的缺陷,Oracle就是我的。此外,我是新来的,所以如果我违反了任何规则我会道歉。谢谢!

1 个答案:

答案 0 :(得分:6)

您可以利用ROW_NUMBER分析函数为每条记录生成唯一的序列号(我们会按升序将该号码分配给日期)。

然后,您按日期和生成的数字之间的差异对日期进行分组 - 连续日期将具有相同的差异:

Date       Number      Difference
01-APR-05       1               1      -- MIN(date_val) in group with diff. = 1
02-APR-05       2               1
03-APR-05       3               1
04-APR-05       4               1
05-APR-05       5               1
06-APR-05       6               1
07-APR-05       7               1      -- MAX(date_val) in group with diff. = 1
11-APR-05       8               3      -- MIN(date_val) in group with diff. = 3
12-APR-05       9               3
13-APR-05      10               3
14-APR-05      11               3
15-APR-05      12               3
16-APR-05      13               3      -- MAX(date_val) in group with diff. = 3

最后,您可以选择每个组中的最小日期和最大日期,以获得每个范围的开始和结束。

以下是查询:

SELECT
    MIN(date_val) start_date,
    MAX(date_val) end_date
  FROM (
    SELECT
        date_val,
        row_number() OVER (ORDER BY date_val) AS rn
      FROM date_tab
  )
GROUP BY date_val - rn
ORDER BY 1
;

输出:

START_DATE   END_DATE 
------------ ----------
01-04-2005   07-04-2005 
11-04-2005   16-04-2005 
19-04-2005   24-04-2005 
26-04-2005   30-04-2005

您可以查看SQLFidlle的工作原理: Dates ranges example