我有两个日期列START_DATE和END_DATE,并且需要获取Oracle中两个日期列之间的日期列表。
START_DATE | END_DATE
04-JUN-19 | 06-JUN-19
11-AUG-19 | 13-AUG-19
对于sql服务器发现了类似的问题,但无法转换为oracle pl / sql:
Need to get dates between two date columns
尝试过,但未显示出预期的结果。
with dates (dte, edte) as (
select A.START_DATE, A.END_DATE
FROM tbl A
WHERE A.START_DATE <> A.END_DATE
union all
select dte + 1, edte
from dates
where dte < edte
)
select dte
from dates;
我想获取列表日期,例如:
2019-06-04
2019-06-05
2019-06-06
2019-08-11
2019-08-12
2019-08-13
但显示:
04-JUN-19
11-AUG-19
答案 0 :(得分:1)
方法如下:
fin_document:
+-------------------+---------------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------------------+---------------------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| dt_payment | date | YES | | NULL |
| total_amount | decimal(10,2) | NO | | 0.00 |
+-------------------+---------------------------+------+-----+---------+----------------+
fin_income:
+------------------+---------------+------+-----+-------------------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------------+---------------+------+-----+-------------------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| document_id | int(11) | YES | MUL | NULL | |
| amount | decimal(10,2) | YES | | 0.00 |
+------------------+---------------+------+-----+-------------------+----------------+
答案 1 :(得分:1)
生成连续整数的一种方法是使用CONNECT BY:
select level n from dual
connect by level <= 3;
N
-
1
2
3
使用Oracle“日期算术”(其中加1意味着增加一天),您可以说:
select date '2019-06-01' + level - 1 dte from dual
connect by level <= 3;
DTE
----------------
2019-06-01 00:00
2019-06-02 00:00
2019-06-03 00:00
最后,如果您具有版本12c或更高版本,则可以使用LATERAL子句将此逻辑应用于每一行。请注意,WITH子查询不是解决方案的一部分,可以在其中生成输入数据。
with data(START_DATE, END_DATE) as (
select date '2019-06-04', date '2019-06-06' from dual
union all
select date '2019-08-11', date '2019-08-13' from dual
)
select * from data, lateral(
select start_date + level - 1 dte
from dual
connect by start_date + level - 1 <= end_date
);
START_DATE END_DATE DTE
---------------- ---------------- ----------------
2019-06-04 00:00 2019-06-06 00:00 2019-06-04 00:00
2019-06-04 00:00 2019-06-06 00:00 2019-06-05 00:00
2019-06-04 00:00 2019-06-06 00:00 2019-06-06 00:00
2019-08-11 00:00 2019-08-13 00:00 2019-08-11 00:00
2019-08-11 00:00 2019-08-13 00:00 2019-08-12 00:00
2019-08-11 00:00 2019-08-13 00:00 2019-08-13 00:00
最好的问候, 炖阿什顿
P.S。如果您使用的是旧版本,则第一个答案(我刚刚看到的)使用相同的逻辑,除了使用TABLE(CAST(MULTISET ...
答案 2 :(得分:1)
在您的问题中,您尝试了SQL标准的递归子查询分解。要使用该技术,我相信您至少需要版本11.2。
with data(START_DATE, END_DATE) as (
select date '2019-06-04', date '2019-06-06' from dual
union all
select date '2019-08-11', date '2019-08-13' from dual
)
, recurse_dates(start_date, end_date, dte) as (
select start_date, end_date, start_date from data
union all
select start_date, end_date, dte + 1
from recurse_dates
where dte < end_date
)
select * from recurse_dates;
START_DATE END_DATE DTE
---------------- ---------------- ----------------
2019-06-04 00:00 2019-06-06 00:00 2019-06-04 00:00
2019-08-11 00:00 2019-08-13 00:00 2019-08-11 00:00
2019-06-04 00:00 2019-06-06 00:00 2019-06-05 00:00
2019-08-11 00:00 2019-08-13 00:00 2019-08-12 00:00
2019-06-04 00:00 2019-06-06 00:00 2019-06-06 00:00
2019-08-11 00:00 2019-08-13 00:00 2019-08-13 00:00
关于, 炖
答案 3 :(得分:0)
通过使用connect by level
中的Oracle
子句,您可以轻松获得结果:
with t( start_date, end_date ) as
(
select date'2019-06-04', date'2019-06-06' from dual union all
select date'2019-06-11', date'2019-06-13' from dual
)
select distinct start_date + level - 1 as "Dates"
from t
connect by level <= end_date - start_date + 1
and prior start_date = start_date
and prior sys_guid() is not null;
Dates
----------
04.06.2019
05.06.2019
06.06.2019
11.06.2019
12.06.2019
13.06.2019
distinct
子句是针对范围之间的重叠日期添加的。
答案 4 :(得分:0)
您的代码可在Oracle 18c上运行:
with dates (dte, edte) as (
select A.START_DATE, A.END_DATE
FROM tbl A
WHERE A.START_DATE <> A.END_DATE
union all
select dte + 1, edte
from dates
where dte < edte
)
select dte
from dates;
输出:
| DTE | | :-------- | | 04-JUN-19 | | 11-JUN-19 | | 05-JUN-19 | | 12-JUN-19 | | 06-JUN-19 | | 13-JUN-19 |
Oracle 18c db <>提琴here
但是,Oracle 11中存在一个错误(编号11840579)(已在11.2.0.3和12.1.0.1中修复),该错误与递归子查询中的日期有关,并且非固定版本的最简单解决方案是添加到日期,但有一个带有非日期列的额外列来处理增量:
WITH dates (dte, edte, step ) AS (
SELECT A.START_DATE, A.END_DATE, 0
FROM tbl A
UNION ALL
SELECT dte, edte, step + 1
FROM dates
WHERE dte + step + 1 <= edte
)
SELECT dte + step
FROM dates;
输出:
| DTE+STEP | | :-------- | | 04-JUN-19 | | 11-JUN-19 | | 05-JUN-19 | | 12-JUN-19 | | 06-JUN-19 | | 13-JUN-19 |
Oracle 11gR2 db <>提琴here