从开始日期到结束日期的每个日期的行

Posted

技术标签:

【中文标题】从开始日期到结束日期的每个日期的行【英文标题】:Row for each date from start date to end date 【发布时间】:2020-10-14 12:20:50 【问题描述】:

我正在尝试做的是记录如下所示:

 Start_DT    End_DT     ID
4/5/2013    4/9/2013    1

并将其更改为如下所示:

    DT      ID
4/5/2013    1
4/6/2013    1
4/7/2013    1
4/8/2013    1
4/9/2013    1

它可以在 Python 中完成,但我不确定 SQL Oracle 是否可以?我很难完成这项工作。任何帮助将不胜感激。

谢谢

【问题讨论】:

【参考方案1】:

使用递归子查询分解子句:

WITH ranges ( start_dt, end_dt, id ) AS (
  SELECT start_dt, end_dt, id
  FROM   table_name
UNION ALL
  SELECT start_dt + INTERVAL '1' DAY, end_dt, id
  FROM   ranges
  WHERE  start_dt + INTERVAL '1' DAY <= end_dt
)
SELECT start_dt,
       id
FROM   ranges;

您的样本数据:

CREATE TABLE table_name ( start_dt, end_dt, id ) AS
SELECT DATE '2013-04-05', DATE '2013-04-09', 1 FROM DUAL

输出:

START_DT | ID :----------------- | -: 2013-04-05 00:00:00 | 1 2013-04-06 00:00:00 | 1 2013-04-07 00:00:00 | 1 2013-04-08 00:00:00 | 1 2013-04-09 00:00:00 | 1

db小提琴here

【讨论】:

递归成员的where子句可以简化为WHERE start_dt &lt; end_dt @GMB 不,如果您的日期包含非午夜时间部分,则不能。如果start_dt2013-04-08 01:23:45end_dt2013-04-09 00:00:00,那么如果您使用start_dt &lt; end_dt,您最终会得到一个在结束日期之后的日期。 确实——但这不是 OP 在他们的示例数据中显示的内容。 此答案不仅适用于 OP,还适用于所有其他有相同问题的用户,如果其中一个人有非午夜约会,那么此答案将按原样工作。如果它仅适用于有限数量的情况(即当start_dtend_dt 具有相同的时间分量时使用start_dt &lt; end_dt),那么会有用户得到他们不期望的答案。【参考方案2】:

按级别连接对这些问题很有用。假设第一个名为“table_DT”的 CTE 是您的表名,因此您可以在之后使用 select 语句。

with table_DT as (
    select 
        to_date('4/5/2013','mm/dd/yyyy') as Start_DT, 
        to_date('4/9/2013', 'mm/dd/yyyy') as End_DT, 
        1 as ID
    from dual
)
select 
    Start_DT + (level-1) as DT, 
    ID
from table_DT
connect by level <= End_DT - Start_DT +1
;

【讨论】:

以上是关于从开始日期到结束日期的每个日期的行的主要内容,如果未能解决你的问题,请参考以下文章

Spark Window Functions:过滤掉开始和结束日期在另一行开始和结束日期范围内的行

如何在 BigQuery 的开始日期和结束日期之间复制生成日期的行?

Oracle SQL 选择具有开始和结束日期的行,如果某些重叠合并行

SSIS - 如何从平面文件插入到具有日期范围的OLE DB?

结束日期不能小于开始日期啥意思

如何为开始日期和结束日期之间的每个工作日创建多行