Oracle 从给定表中获取数据范围之间的特定日期

Oracle 从给定表中获取数据范围之间的特定日期,oracle,Oracle,我读了很多介绍使用connect by的文章,但所有这些文章都是从给定的参数中获得特定的日期,通常是开始日期和结束日期 我想知道的是如何从某个表中拆分行? 范例 我想要的结果是 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 0

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

我想要的结果是

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 ) ; 
等待您的解决方案。谢谢。

测试数据:

查询:


以下是使用递归cte的标准SQL中的查询,该查询也适用于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;
输出:

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

如果要使用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

请添加您已经尝试过的内容,不要直接要求解决方案,因为这将被投票决定结束。相反,在你的问题中添加一些格式,在这里写下你已经尝试过的内容并征求建议,而不是直接寻求解决方案。谢谢你的格式设置。我试图通过选择T_ID,T1.StartDate+LEVEL-1 DD,LEVEL FROM T1,其中T1.T_ID in='01'按级别连接来检索数据,为什么您想要的结果中T_ID=02只有一天2017-06-06。2017-06-05发生了什么事?如果您只需要不同的日期,您希望如何处理与同一日期关联的不同T_ID?谢谢..我添加了它。谢谢您的重播。似乎是例外01436。00000-用户数据中的循环连接是警告…感谢更新。最新查询仅获取startDate,但未将其拆分抱歉…仍然不起作用..00942。00000-表或视图不可用exist@Lobs在Oracle 11g中为我工作。哪一个表或视图不存在?第一个分层查询将生成指数数量的行作为输入的数量-您正在使用DISTINCT删除它们,但效率非常低。我更新了该注释-删除DISTINCT关键字并添加几个更大范围的行,您将很快看到数据的指数增长查询输出及其效率。递归查询也是的一个版本,它添加了一个不必要的自联接。@MT0:我写过我不确定性能。我只是想让他看些东西。实际上,从这个问题来看,我们不知道表中会有多少条记录,也许只有两条。然后我给出了另一个选择。PS:我不认为更新评论是正确的:现在人们可以认为我给你的第一个评论是没有动机的。。。
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
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;
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 
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
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