像这样创建日历数据库 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 小时。
我想创建一个像这样的日历 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 小时。