像这样创建日历数据库 table

Create a calendar database table like this

我想创建一个像这样的日历 SQL table,但要使用几年。 (我正在使用 mysql 5.7.28) 日期为 DD-MM-YYYY

可能吗?

如果你是运行MySQL8.0,可以使用递归查询:

with recursive cte as (
    select '2019-01-01 00:00:00' dt
    union all 
    select dt + interval 1 hour from cte where dt < '2020-01-01' - interval 1 hour
)
select
    row_number() over(order by dt) id,
    date(dt) day,
    time(dt) start_hour,
    time(dt + interval 1 hour) end_hour
from cte

递归 cte 在给定边界(此处为 2019 年)之间生成一个 datetime 列表,增量为 1 小时。然后,外部查询通过提取日期和小时部分生成预期结果。

您可以根据您的具体要求调整边界和增量。

旁注:我建议在日历中也保留完整的日期时间 table;在许多情况下,具有适当的日期时间值比单独的日期和时间更方便。

Demo on DB Fiddle 仅限第一天:

id | day        | start_hour      | end_hour       
-: | :--------- | :-------------- | :--------------
 1 | 2019-01-01 | 00:00:00.000000 | 01:00:00.000000
 2 | 2019-01-01 | 01:00:00.000000 | 02:00:00.000000
 3 | 2019-01-01 | 02:00:00.000000 | 03:00:00.000000
 4 | 2019-01-01 | 03:00:00.000000 | 04:00:00.000000
 5 | 2019-01-01 | 04:00:00.000000 | 05:00:00.000000
 6 | 2019-01-01 | 05:00:00.000000 | 06:00:00.000000
 7 | 2019-01-01 | 06:00:00.000000 | 07:00:00.000000
 8 | 2019-01-01 | 07:00:00.000000 | 08:00:00.000000
 9 | 2019-01-01 | 08:00:00.000000 | 09:00:00.000000
10 | 2019-01-01 | 09:00:00.000000 | 10:00:00.000000
11 | 2019-01-01 | 10:00:00.000000 | 11:00:00.000000
12 | 2019-01-01 | 11:00:00.000000 | 12:00:00.000000
13 | 2019-01-01 | 12:00:00.000000 | 13:00:00.000000
14 | 2019-01-01 | 13:00:00.000000 | 14:00:00.000000
15 | 2019-01-01 | 14:00:00.000000 | 15:00:00.000000
16 | 2019-01-01 | 15:00:00.000000 | 16:00:00.000000
17 | 2019-01-01 | 16:00:00.000000 | 17:00:00.000000
18 | 2019-01-01 | 17:00:00.000000 | 18:00:00.000000
19 | 2019-01-01 | 18:00:00.000000 | 19:00:00.000000
20 | 2019-01-01 | 19:00:00.000000 | 20:00:00.000000
21 | 2019-01-01 | 20:00:00.000000 | 21:00:00.000000
22 | 2019-01-01 | 21:00:00.000000 | 22:00:00.000000
23 | 2019-01-01 | 22:00:00.000000 | 23:00:00.000000
24 | 2019-01-01 | 23:00:00.000000 | 00:00:00.000000

在早期版本中,您通常会通过交叉连接子查询创建大量 table 数字,并使用数字范围来增加初始日期。 row_number() 可以用 MySQL 变量模拟:

select
    @id:=@id + 1 id,
    date(dt) day,
    time(dt) start_hour,
    time(dt + interval 1 hour) end_hour,
    0 prenoted
from (
    select '2019-01-01' + interval d0.n + 10 * d1.n + 100 * d2.n + 1000 * d3.n hour dt
    from 
        (
            select 0 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
        ) d0
        cross join (
            select 0 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 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 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
    where '2019-01-01' + interval d0.n + 10 * d1.n + 100 * d2.n + 1000 * d3.n hour < '2020-01-01'
) t
cross join (select @id := 0 id) i
order by dt

以上查询给出的最大跨度为 10 000 小时(代表略多于 416 天);您可以添加另一个交叉连接并更新算法以处理最多 100 000 小时(等等)。

Demo on DB Fiddle 第一个 24 小时。