我有一个带有以下各列的表:
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
您需要一个数字表...创建一个临时表或虚拟表,其中包含数字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)
这里是一种方法。
这将使用内联视图(别名为i
来生成从0到999的整数值,并且与表连接以生成多达1000个日期值,从每行的开始日期到结束日期。
内联视图i
可以很容易地扩展以按照相同的模式生成10,000或100,000行。
这假定startdate
和enddate
列是数据类型DATE
。 (或DATETIME
或TIMESTAMP
或可以隐式转换为有效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)
我知道答案很晚了但还是使用递归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函数中的更改很少。