从日期选择期间

时间:2018-02-19 09:12:44

标签: sql oracle date gaps-and-islands

我有一个问题,就是从缺席清单中选择,那些跟随彼此并将它们分组到期间。

date_from (data_od)  date_to(data_do)
--------------------------
18/08/01 -  18/08/15
18/08/16 -  18/08/20
18/08/21 -  18/08/31
18/09/01 -  18/09/08
18/05/01 -  18/05/31
18/06/01 -  18/06/30
18/03/01 -  18/03/18
18/02/14 -  18/02/28

上面是缺席列表,其结果应该是一个表格:

date_from (data_od)  date_to(data_do)
--------------------------
18/08/01    18/09/08
18/05/01    18/06/30
18/02/14    18/03/18

现在,我做了类似的事情,但我只研究过两次:(

 SELECT u1.data_od,u2.data_do
        FROM l_absencje u1 CROSS APPLY
          (SELECT *  FROM l_absencje labs
              WHERE labs.prac_id=u1.prac_id AND 
               TRUNC(labs.data_od) = TRUNC(u1.data_do)+1
             ORDER BY id DESC FETCH FIRST 1 ROWS ONLY
          ) u2 where u1.prac_id=1067 ;

并告诉我:

18/08/01    18/08/20 bad
18/08/16    18/08/31 bad
18/08/21    18/09/08 bad
18/05/01    18/06/30 good 
18/02/14    18/03/18 good

1 个答案:

答案 0 :(得分:2)

您可以结合使用var contentDisposition = response.headers('Content-Disposition'); var filename = contentDisposition.split(';')[1].split('filename')[1].split('=')[1].trim(); LAG()LEAD()分析函数:

SQL Fiddle

Oracle 11g R2架构设置

LAST_VALUE()

查询1

CREATE TABLE absences ( date_from, date_to ) AS
SELECT DATE '2018-08-01', DATE '2018-08-15' FROM DUAL UNION ALL
SELECT DATE '2018-08-16', DATE '2018-08-20' FROM DUAL UNION ALL
SELECT DATE '2018-08-21', DATE '2018-08-31' FROM DUAL UNION ALL
SELECT DATE '2018-09-01', DATE '2018-09-08' FROM DUAL UNION ALL
SELECT DATE '2018-05-01', DATE '2018-05-31' FROM DUAL UNION ALL
SELECT DATE '2018-06-01', DATE '2018-06-30' FROM DUAL UNION ALL
SELECT DATE '2018-03-01', DATE '2018-03-18' FROM DUAL UNION ALL
SELECT DATE '2018-02-14', DATE '2018-02-28' FROM DUAL;

<强> Results

SELECT *
FROM   (
  SELECT CASE
         WHEN date_to IS NOT NULL
         THEN LAST_VALUE( date_from ) IGNORE NULLS
                OVER( ORDER BY ROWNUM )
         END AS date_from,
         date_to
  FROM   (
    SELECT CASE date_from
           WHEN LAG( date_to ) OVER ( ORDER BY date_to )
                + INTERVAL '1' DAY
           THEN NULL
           ELSE date_from
           END AS date_from,
           CASE date_to
           WHEN LEAD( date_from ) OVER ( ORDER BY date_from )
                - INTERVAL '1' DAY
           THEN NULL
           ELSE date_to
           END AS date_to
    FROM   absences
  )
)
WHERE  date_from IS NOT NULL
AND    date_to IS NOT NULL