基于两列中的日期范围重复行

问题描述 投票:2回答:3

我有一个带有以下各列的表:

ID startdate enddate

我希望将此表的行重复开始日期和结束日期之间的差值,并重复一列,该列为表中的每个ID提供这两天之间的所有日期。因此,我的新表应如下所示:

ID Date

A startdate
A startdate +1 day
A startdate +2 days (till enddate)
B startdate
B startdate + 1 day ....

请注意,对于不同的ID,我有不同的开始和结束日期。

我尝试了以下问题的答案,但这不起作用:

Mysql select multiple rows based on one row related date range

mysql date range rows repeat
3个回答
1
投票

您需要一个数字表...创建一个临时表或虚拟表,其中包含数字1到X(X是两个日期之间的最大可能差值]

然后使用日期差异连接到该表

恐怕我是SQL Server,所以不确定datediff函数在mysql中的工作方式是否相同,但是您应该明白这一点。

SELECT
    DateTable.Id,
    DATEADD(dd, NumbersTable.Number, DateTable.StartDate)
FROM
    DateTable
INNER JOIN
    NumbersTable
ON
    DATEADD(dd, NumbersTable.Number, DateTable.StartDate) <= DateTable.EndDate
ORDER BY
    DateTable.Id,
    DATEADD(dd, NumbersTable.Number, DateTable.StartDate)

3
投票

这里是一种方法。

这将使用内联视图(别名为i来生成从0到999的整数值,并且与表连接以生成多达1000个日期值,从每行的开始日期到结束日期。

内联视图i可以很容易地扩展以按照相同的模式生成10,000或100,000行。

这假定startdateenddate列是数据类型DATE。 (或DATETIMETIMESTAMP或可以隐式转换为有效DATE值的数据类型。

SELECT t.id
     , t.startdate + INTERVAL i.i DAY AS `Date`
  FROM ( SELECT d3.n*100 + d2.n*10 + d1.n AS i
           FROM ( SELECT 0 AS n 
                   UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3
                   UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6
                   UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9
                ) d1
          CROSS
           JOIN ( SELECT 0 AS n 
                   UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3
                   UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6
                   UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9
                ) d2
          CROSS
           JOIN ( SELECT 0 AS n 
                   UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3
                   UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6
                   UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9
                ) d3
       ) i
  JOIN mytable t
    ON i.i <= DATEDIFF(t.enddate,t.startdate)

0
投票

我知道答案很晚了但还是使用递归cte的另一个答案

with  recursive cte ( id, startdate) as
(
select id,startdate  from test t1
union all
select t2.id,(c.startdate + interval '1 day')::date
from test t2
 join cte c on c.id=t2.id and (c.startdate + interval '1 day')::date<=t2.enddate
)
select id,startdate as date from cte
order by id, startdate

其特定于PostgreSQL,但它应该可以在其他关系数据库中工作,而Date函数中的更改很少。

© www.soinside.com 2019 - 2024. All rights reserved.