MySQL 8.0.11 生成日历表

MySQL的date 数据类支持的时间范围是 1000-1-1 到9999-12-31,通过计算可以知道最大支持天数为3287181天属于百万级别的。


mysql> SELECT DATEDIFF('9999-12-31','1000-01-01') days;
+---------+
| days    |
+---------+
| 3287181 |
+---------+
1 row in set (0.28 sec)

为了生产百万数据的日历,我们可以使用如下代码生成日历,当然在实际应用中可能只需要上千或者万条记录就够了(10年也就是3650条数据记录)。

创建一个表存储数字0到9,在创建一个表存储日期,然后通过添加字段扩展显示。
 CREATE TABLE if not exists num (i int);
INSERT INTO num (i) VALUES (0), (1), (2), (3), (4), (5), (6), (7), (8), (9);
CREATE TABLE  if not exists calendar(dateseq date);
--自2018-01-01开始生成100万条日历记录:
INSERT INTO calendar(dateseq) SELECT
    ADDDATE(
        (   -- 这里的起始日期,你可以换成当前日期
            DATE_FORMAT("2018-1-1", '%Y-%m-%d') 
        ),
        numlist.id
    ) AS `date`
FROM
    (
        SELECT
            n1.i + n10.i * 10 + n100.i * 100 + n1000.i * 1000+ n10000.i * 10000 +n100000.i*100000   AS id
           
        FROM
            num n1
        CROSS JOIN num AS n10
        CROSS JOIN num AS n100
        CROSS JOIN num AS n1000
        CROSS JOIN num AS n10000
        CROSS JOIN num AS n100000
        ) AS numlist;
Query OK, 1000000 rows affected (16.67 sec)
Records: 1000000  Duplicates: 0  Warnings: 0
耗时16.67s即生成了100万条日历的记录。
mysql> SELECT MIN(dateseq),MAX(dateseq),COUNT(1) FROM calendar;                
+--------------+--------------+----------+
| MIN(dateseq) | MAX(dateseq) | COUNT(1) |
+--------------+--------------+----------+
| 2018-01-01   | 4755-11-28   |  1000000 |
+--------------+--------------+----------+
1 row in set (1.02 sec)

有了上面的数据我们可以生成BI报表中经常需要的使用时间维度的表。

CREATE TABLE dim_calendar(
id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY COMMENT '自增主键',
dateseq DATE NOT NULL COMMENT '日期序列,格式YYYY-MM-DD',
year_digital INT NOT NULL COMMENT '年份,2018',
quarter_digital TINYINT COMMENT '季度,1--4',
month_digital TINYINT COMMENT '月份,数字月份,1--12',
peroid_date INT COMMENT '日期,20180725',
peroid_month INT COMMENT '月份,201807',
period_week TINYINT COMMENT '一年的中的第几周,1-53',
weekseq  TINYINT COMMENT '周几,1-7',
year_day INT COMMENT '一年中的第几天,1--366',
month_day INT COMMENT '当月的第几天 ,1-31'
)
COMMENT '日历维度表';

利用上面的的日历表可以生成时间维度表的数据:

--插入数据:
INSERT INTO dim_calendar(dateseq,year_digital,quarter_digital,month_digital,peroid_date,peroid_month,period_week,weekseq,year_day,month_day)
SELECT
  dateseq,YEAR(dateseq),QUARTER(dateseq),MONTH(dateseq),DATE_FORMAT(dateseq,'%Y%m%d'),DATE_FORMAT(dateseq,'%Y%m'),WEEKOFYEAR(dateseq),DAYOFWEEK(dateseq)-1,DAYOFYEAR(dateseq),DAYOFMONTH(dateseq)
FROM calendar;

--查询验证:
mysql> select * from dim_calendar where dateseq='2018-07-25'\G
*************************** 1. row ***************************
             id: 206
        dateseq: 2018-07-25
   year_digital: 2018
quarter_digital: 3
  month_digital: 7
    peroid_date: 20180725
   peroid_month: 201807
    period_week: 30
        weekseq: 3
       year_day: 206
      month_day: 25
1 row in set (0.00 sec)

猜你喜欢

转载自blog.csdn.net/vkingnew/article/details/81194090