使用select语句查询日期范围

时间:2016-06-07 20:17:30

标签: sql oracle

我想知道这是可能的,使用select语句查询生成日期范围(即start_date列和end_date列),间隔为10天,最多为62天,返回sysdate。如下所示

需要

结果

enter image description here 请帮助任何人

感谢你

2 个答案:

答案 0 :(得分:1)

解决问题的原始版本:

查询1 - 分层查询

SELECT TRUNC( SYSDATE ) - LEVEL * 10 AS start_date,
       TRUNC( SYSDATE ) - ( LEVEL - 1 ) * 10 AS end_date
FROM   DUAL
CONNECT BY LEVEL <= 5

查询2 - 递归子查询

WITH rsqfc ( end_date, lvl ) AS (
  SELECT CAST( TRUNC( SYSDATE ) AS DATE ), 1 FROM DUAL
UNION ALL
  SELECT end_date - 10, lvl + 1
  FROM   rsqfc
  WHERE  lvl < 5
)
SELECT end_date - 10 AS start_date,
       end_date
FROM   rsqfc;

<强>输出

(两者输出相同)

START_DATE          END_DATE          
------------------- -------------------
2016-05-28 00:00:00 2016-06-07 00:00:00 
2016-05-18 00:00:00 2016-05-28 00:00:00 
2016-05-08 00:00:00 2016-05-18 00:00:00 
2016-04-28 00:00:00 2016-05-08 00:00:00 
2016-04-18 00:00:00 2016-04-28 00:00:00 

更新:解决编辑问题 - 只需更改间隔并使用GREATESTLEAST

查询1 - 分层查询

SELECT TRUNC( SYSDATE ) - LEAST( 62, LEVEL * 11 ) AS start_date,
       TRUNC( SYSDATE ) - ( LEVEL - 1 ) * 10 AS end_date
FROM   DUAL
CONNECT BY LEVEL <= 6

查询1 - 递归子查询

WITH rsqfc ( end_date, lvl ) AS (
  SELECT CAST( TRUNC( SYSDATE ) AS DATE ), 1 FROM DUAL
UNION ALL
  SELECT end_date - 11, lvl + 1
  FROM   rsqfc
  WHERE  lvl < 6
)
SELECT GREATEST( TRUNC( SYSDATE ) - 62, end_date - 10 ) AS start_date,
       end_date
FROM   rsqfc;

<强>输出

START_DATE          END_DATE          
------------------- -------------------
2016-05-28 00:00:00 2016-06-08 00:00:00 
2016-05-17 00:00:00 2016-05-29 00:00:00 
2016-05-06 00:00:00 2016-05-19 00:00:00 
2016-04-25 00:00:00 2016-05-09 00:00:00 
2016-04-14 00:00:00 2016-04-29 00:00:00 
2016-04-07 00:00:00 2016-04-19 00:00:00 

答案 1 :(得分:0)

在看到您的修改后,我发现这有点棘手。您仍然会使用递归查询来生成日期范围,但由于最后一个日期范围实际上可能少于10天,您必须添加一个case语句将其限制为62天。

递归查询的第一部分将END_DT = SYSDATE和START_DT设置为SYSDATE - 10天。第二部分将从日期中减去,直至达到70天。然后select语句将最后一个START_DT更改为62天。

with cte(START_DT, END_DT) 
as(
  select 
  trunc(SYSDATE) - 10  as START_DT, 
  trunc(SYSDATE)       as END_DT 
from dual
union all
  Select 
  START_DT - 11 as START_DT, 
  START_DT - 1  as END_DT
from cte
where START_DT - 11 >= trunc(SYSDATE) - 70
)    

select 
  case when trunc(START_DT) < trunc(SYSDATE) - 62 
       then trunc(SYSDATE) - 62 
       else START_DT
  end START_DT,
  END_DT
from cte
order by start_dt desc

<强>输出:

START_DT             END_DT             
-------------------- --------------------
29-MAY-2016 00:00:00 08-JUN-2016 00:00:00 
18-MAY-2016 00:00:00 28-MAY-2016 00:00:00 
07-MAY-2016 00:00:00 17-MAY-2016 00:00:00 
26-APR-2016 00:00:00 06-MAY-2016 00:00:00 
15-APR-2016 00:00:00 25-APR-2016 00:00:00 
07-APR-2016 00:00:00 14-APR-2016 00:00:00