3

我有一个包含以下列的表格:

ID startdate enddate

我希望该表的行重复与 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根据一行相关的日期范围选择多行

4

3 回答 3

4

这是一种方法。

这使用内联视图(别名为i生成从 0 到 999 的整数值,并且连接到您的表以生成最多 1000 个日期值,从 startdate 开始到每行的 enddate。

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

这假定startdateenddate列是 datatype 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)
于 2013-02-08T22:56:03.433 回答
2

您需要一个数字表...创建一个包含数字 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)
于 2013-02-08T22:31:25.847 回答
2

我知道回答很晚了,但使用递归 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 函数的变化很小。

于 2020-05-24T09:32:44.133 回答