我有一个有两个日期列的表格,如何获取这两个日期之间的日期并一一列出。 这是测试脚本:
CREATE TABLE t1
AS
SELECT DATE '2020-1-31' AS startdate,
DATE '2020-2-3' AS enddate
FROM dual
UNION
SELECT DATE '2020-2-27' AS startdate,
DATE '2020-3-3' AS enddate
FROM dual;
SELECT *
FROM t1;
DROP TABLE t1;
我期待的结果集是:
我该如何查询? 预先感谢。
给你:
SQL> select * From t1;
STARTDATE ENDDATE
---------- ----------
01/31/2020 02/03/2020
02/27/2020 03/03/2020
SQL> select a.startdate, a.enddate,
2 a.startdate + column_value - 1 dt
3 from t1 a cross join
4 table(cast(multiset(select level from dual
5 connect by level <= a.enddate - a.startdate + 1
6 ) as sys.odcinumberlist))
7 order by dt;
STARTDATE ENDDATE DT
---------- ---------- ----------
01/31/2020 02/03/2020 01/31/2020
01/31/2020 02/03/2020 02/01/2020
01/31/2020 02/03/2020 02/02/2020
01/31/2020 02/03/2020 02/03/2020
02/27/2020 03/03/2020 02/27/2020
02/27/2020 03/03/2020 02/28/2020
02/27/2020 03/03/2020 02/29/2020
02/27/2020 03/03/2020 03/01/2020
02/27/2020 03/03/2020 03/02/2020
02/27/2020 03/03/2020 03/03/2020
10 rows selected.
SQL>
这被称为行生成器技术(如果你也想用谷歌搜索)。
替代解决方案
创建表格 -
create table mytable(start_date date, end_date date);
加载数据 -
insert into mytable values (to_date('01/31/2020','mm/dd/yyyy'),to_date('02/03/2020','mm/dd/yyyy'));
SQL 检索给定日期范围之间的日期列表 -
select
t.start_date + rownum -1 as dt,
t.start_date,
t.end_date
from
all_objects, mytable t
where
rownum <=
t.end_date- t.start_date+1;
db 小提琴 - https://dbfiddle.uk/?rdbms=oracle_11.2&fiddle=7cd81f5892ad195b72ee1d22a3b44e2a
对于实际的 Oracle 版本:
SELECT *
FROM t1,
lateral(
select level N,
t1.startdate+level-1 dt
from dual
connect by level <= t1.enddate - t1.startdate + 1
);
或
SELECT
startdate,
enddate,
startdate+n as DT
FROM t1,
xmltable('0 to xs:integer(.)'
passing cast(enddate-startdate as number)
columns n int path '.'
)
完整示例:
with t1
AS (
SELECT DATE '2020-1-31' AS startdate,
DATE '2020-2-3' AS enddate
FROM dual
UNION
SELECT DATE '2020-2-27' AS startdate,
DATE '2020-3-3' AS enddate
FROM dual
)
SELECT *
FROM t1,
lateral(
select level N,
t1.startdate+level-1 dt
from dual
connect by level <= t1.enddate - t1.startdate + 1
);
with t1
AS (
SELECT DATE '2020-1-31' AS startdate,
DATE '2020-2-3' AS enddate
FROM dual
UNION
SELECT DATE '2020-2-27' AS startdate,
DATE '2020-3-3' AS enddate
FROM dual
)
SELECT
startdate,
enddate,
startdate+n as DT
FROM t1,
xmltable('0 to xs:integer(.)'
passing cast(enddate-startdate as number)
columns n int path '.'
);
要生成日期之间的日期列表,这是最简单的方法:
以2024年10月1日到2024年10月30日为例,将生成30条日期记录。
SELECT TRUNC(DATE '2024-10-01')-1 + LEVEL, LEVEL
FROM DUAL CONNECT BY LEVEL < ABS(DATE '2024-10-01' - DATE '2024-11-01') -- Specify Date range here this will just result in a int for number of days
ORDER BY LEVEL
如果您需要10月1日至11月1日(含),只需按条件连接即可<= instead of <
或者如果您想从起始日期生成 10 条日期记录:
SELECT TRUNC(DATE '2024-10-01')-1 + LEVEL, LEVEL
FROM DUAL CONNECT BY LEVEL <= 10
ORDER LEVEL
简单,不需要特殊的oracle版本。