在给出表格的数据范围之间获取特定日期

时间:2017-07-10 08:17:50

标签: oracle

我阅读了很多介绍connect by使用的文章,但是所有这些文章都从给定参数(几乎是开始日期和结束日期)中获取特定日期 我想知道的是如何从某个表中拆分行? 实施例

Table T1
StartDate      EndDate        T_ID
2017-06-01     2017-06-15      01
2017-06-05     2017-06-06      02

我想要的结果是

TargetDate    T_ID
2017-06-01    01
2017-06-02    01
2017-06-03    01
2017-06-04    01
2017-06-05    01
.
.
.
.
2017-06-15    01
2017-06-06    01
2017-06-06    02

我试过

 SELECT T_ID, T1.StartDate+ LEVEL - 1 DD, LEVEL 
 FROM T1 
 WHERE T1.T_ID in = '01' 
  CONNECT BY LEVEL <= (TO_DATE(TRUNC(T1.EndDate)) - T1.StartDate + 1 ) ; 

等待您的解决方案。感谢。

4 个答案:

答案 0 :(得分:1)

测试数据

CREATE TABLE t1 ( t_id, startdate, enddate ) AS
  SELECT 1, DATE '2017-06-01', DATE '2017-06-15' FROM DUAL UNION ALL
  SELECT 2, DATE '2017-06-05', DATE '2017-06-06' FROM DUAL;

<强>查询

SELECT  T_ID,
        COLUMN_VALUE AS dt,
        ROW_NUMBER() OVER ( PARTITION BY t1.ROWID
                            ORDER BY Column_value ) AS lvl 
FROM    T1
        CROSS JOIN
        TABLE(
          CAST(
            MUTLTSET(
              SELECT     t1.Startdate + LEVEL - 1
              FROM       DUAL
              CONNECT BY t1.Startdate + LEVEL - 1 <= t1.EndDate
            ) AS SYS.ODCIDATELIST
          )
        );

<强>输出

T_ID DT         LVL
---- ---------- ---
   1 2017-06-01   1
   1 2017-06-02   2
   1 2017-06-03   3
   1 2017-06-04   4
   1 2017-06-05   5
   1 2017-06-06   6
   1 2017-06-07   7
   1 2017-06-08   8
   1 2017-06-09   9
   1 2017-06-10  10
   1 2017-06-11  11
   1 2017-06-12  12
   1 2017-06-13  13
   1 2017-06-14  14
   1 2017-06-15  15
   2 2017-06-05   1
   2 2017-06-06   2

答案 1 :(得分:1)

以下是标准SQL中的查询(带有递归cte),它也适用于Oracle:

with all_dates(targetdate, t_id, enddate) as
(
  select startdate as targetdate, t_id, enddate from t1
  union all
  select targetdate + 1, t_id, enddate from all_dates where targetdate < enddate
)
select targetdate, t_id 
from all_dates
order by t_id, targetdate;

答案 2 :(得分:0)

SELECT DISTINCT T_ID
      , T1.StartDate+ LEVEL - 1 DD
      , LEVEL     
FROM T1 
WHERE T1.T_ID IN( 1,2)
CONNECT BY LEVEL <= T1.EndDate - T1.StartDate + 1 

但是我对表演不确定(目前我没有找到一种方法来限制没有DISTINCT但是使用CONNECT BY子句。)

作为替代方案,您可以使用这样的CTE(您可以删除RN列,我将其留作支票):

with all_dates(targetdate, t_id, enddate, RN) as
(
  select startdate as targetdate, t_id, enddate, 1 AS RN from t1
  union all
  select T1.startdate + all_dates.RN, T1.t_id, T1.enddate, all_dates.RN+1 AS RN
  from t1 
  inner JOIN all_dates ON T1.startdate+all_dates.RN<=all_dates.enddate
   AND T1.T_ID = all_dates.T_ID
)
select targetdate, t_id , RN
from all_dates
order by t_id, targetdate;

示例数据:

CREATE TABLE T1 (StartDate DATE, EndDate DATE, T_ID NUMBER(10,0));
INSERT INTO T1 VALUES ('20170601','20170615', 1);
INSERT INTO T1 VALUES ('20170605','20170606', 2);
INSERT INTO T1 VALUES ('20170701','20170703', 3);

输出:

20170601    1   1
20170602    1   2
20170603    1   3
20170604    1   4
20170605    1   5
20170606    1   6
20170607    1   7
20170608    1   8
20170609    1   9
20170610    1   10
20170611    1   11
20170612    1   12
20170613    1   13
20170614    1   14
20170615    1   15
20170605    2   1
20170606    2   2
20170701    3   1
20170702    3   2
20170703    3   3

答案 3 :(得分:0)

如果您想要使用connect by来实现此目的,则需要添加一些附加条款才能使其与多行一起使用:

WITH t1 AS (SELECT to_date('01/06/2017', 'dd/mm/yyyy') startdate, to_date('15/06/2017', 'dd/mm/yyyy') enddate, 1 t_id FROM dual UNION ALL
            SELECT to_date('05/06/2017', 'dd/mm/yyyy') startdate, to_date('06/06/2017', 'dd/mm/yyyy') enddate, 2 t_id FROM dual)
SELECT t_id,
       startdate + LEVEL -1 dd
FROM   t1
CONNECT BY LEVEL <= enddate - startdate + 1
AND        PRIOR t_id = t_id
AND        PRIOR sys_guid() IS NOT NULL
ORDER BY t_id, dd;

      T_ID DD
---------- -----------
         1 01/06/2017
         1 02/06/2017
         1 03/06/2017
         1 04/06/2017
         1 05/06/2017
         1 06/06/2017
         1 07/06/2017
         1 08/06/2017
         1 09/06/2017
         1 10/06/2017
         1 11/06/2017
         1 12/06/2017
         1 13/06/2017
         1 14/06/2017
         1 15/06/2017
         2 05/06/2017
         2 06/06/2017
相关问题