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