将日期合并为连续日期

时间:2016-06-22 09:07:45

标签: sql oracle gaps-and-islands

|Resource ID | Start Date | End Date|
-------------------------------------
|24565865    | 04-01-16   | 29-01-16|
|24565865    | 29-01-16   | 01-02-16|    
|24565865    | 01-02-16   | 25-03-16| 
|24565865    | 25-03-16   | 01-04-16|
|24565865    | 01-04-16   | 09-05-16|
|24565865    | 09-05-16   | 13-05-16|
|24565865    | 13-05-16   | 25-07-16|
|24565865    | 25-07-16   | 01-08-16|
|24565865    | 01-08-16   | 12-12-99|

希望显示这些日期,例如

|Resource ID | Start Date | End Date|
-------------------------------------
|24565865    |04-01-2016  |25-03-2016|
|24565865    |01-04-2016  |12-12-2099|

SELECT 
    o.asset_id,o.path,RB.RESOURCE_ID,rl.start_date,rl.end_date
    ,o.resourcemanager_id,rl.resourcemanager_id 
FROM 
    objectbase o 
JOIN 
    resourcelock rl 
ON
    o.resourcemanager_id=rl.resourcemanager_id
JOIN 
    resourcebase rb 
ON
    rb.resource_id=O.ASSET_ID
WHERE 
    RB.RESOURCE_ID=24565865 AND O.CODE LIKE '186' 
ORDER BY 
    RL.START_DATE;

以上是查询

2 个答案:

答案 0 :(得分:0)

您可以结合使用LAG()LEAD()LAST_VALUE()分析函数:

SELECT *
FROM   (
  SELECT resource_id,
         CASE
         WHEN end_date IS NOT NULL
         THEN LAST_VALUE( start_date ) IGNORE NULLS
                OVER( PARTITION BY resource_id ORDER BY ROWNUM )
         END AS start_date,
         end_date
  FROM   (
    SELECT resource_id,
           CASE start_date
           WHEN LAG( end_date )
                  OVER ( PARTITION BY resource_id ORDER BY end_date )
           THEN NULL
           ELSE start_date
           END AS start_date,
           CASE end_date
           WHEN LEAD( start_date )
                  OVER ( PARTITION BY resource_id ORDER BY end_date )
           THEN NULL
           ELSE end_date
           END AS end_date
    FROM   (
      -- your query
    )
  )
)
WHERE  start_date IS NOT NULL
AND    end_date IS NOT NULL

答案 1 :(得分:0)

这是另一种方式:

with sample_data as (select 24565865 resource_id, to_date('04/01/2016', 'dd/mm/yyyy') start_date, to_date('29/01/2016', 'dd/mm/yyyy') end_date from dual union all
                     select 24565865 resource_id, to_date('29/01/2016', 'dd/mm/yyyy') start_date, to_date('01/02/2016', 'dd/mm/yyyy') end_date from dual union all
                     select 24565865 resource_id, to_date('01/02/2016', 'dd/mm/yyyy') start_date, to_date('25/03/2016', 'dd/mm/yyyy') end_date from dual union all
--                     select 24565865 resource_id, to_date('25/03/2016', 'dd/mm/yyyy') start_date, to_date('01/04/2016', 'dd/mm/yyyy') end_date from dual union all
                     select 24565865 resource_id, to_date('01/04/2016', 'dd/mm/yyyy') start_date, to_date('09/05/2016', 'dd/mm/yyyy') end_date from dual union all
                     select 24565865 resource_id, to_date('09/05/2016', 'dd/mm/yyyy') start_date, to_date('13/05/2016', 'dd/mm/yyyy') end_date from dual union all
                     select 24565865 resource_id, to_date('13/05/2016', 'dd/mm/yyyy') start_date, to_date('25/07/2016', 'dd/mm/yyyy') end_date from dual union all
                     select 24565865 resource_id, to_date('25/07/2016', 'dd/mm/yyyy') start_date, to_date('01/08/2016', 'dd/mm/yyyy') end_date from dual union all
                     select 24565865 resource_id, to_date('01/08/2016', 'dd/mm/yyyy') start_date, to_date('12/12/2099', 'dd/mm/yyyy') end_date from dual)
select   resource_id,
         min(start_date) start_date,
         max(end_date) end_date
from     (select resource_id,
                 start_date,
                 end_date,
                 sum(sum_col) over (partition by resource_id order by start_date) grp
          from   (select resource_id,
                         start_date,
                         end_date,
                         case when lag(end_date, 1, start_date-1) over (partition by resource_id order by start_date) != start_date then 1 else 0 end sum_col
                  from   sample_data))
group by resource_id,
         grp;

RESOURCE_ID START_DATE END_DATE  
----------- ---------- ----------
   24565865 04-01-2016 25-03-2016
   24565865 01-04-2016 12-12-2099