mysql 8.0 日期维度表生成(可运行)

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
RDS MySQL Serverless 高可用系列,价值2615元额度,1个月
简介: mysql 8.0 日期维度表生成(可运行)

日期维度表左右

在数据仓库(Data Warehouse)中,日期维度表(Date Dimension Table)是非常重要的,因为大多数业务数据都涉及时间维度。日期维度表提供了丰富的日期信息,帮助用户进行时间相关的数据分析和报表生成。具体作用包括:

  • 提供标准化的日期信息

日期维度表为每个日期提供了标准化的、多种格式的日期表示,如短日期、中日期、长日期、完整日期等。这些格式可以满足不同的业务需求,使得在数据展示时更加灵活。

  • 支持多种时间粒度的分析

日期维度表提供了丰富的时间粒度信息,例如:

年、月、季度、周等字段,可以方便地进行按年、按月、按季度或按周的分析。

一年中的第几天(day_in_year)、一月中的第几天(day_in_month)、周的第一天或最后一天等字段,支持更细致的时间计算和汇总分析。

  • 支持日期的国际化

通过存储英文和中文等不同语言的日期格式和星期几、月份的名称,日期维度表可以适应国际化需求,支持多语言环境下的数据展示和分析。

  • 支持复杂的时间维度计算

日期维度表预先计算了一些复杂的时间逻辑,如:


周的第一天和最后一天(is_first_day_in_week 和 is_last_day_in_week),方便做周度数据分析。

月份和季度的起止日期(is_first_day_in_month、is_last_day_in_month),帮助识别月度或季度的起止时间。

季度编号和年度季度(quarter_number、year_quarter),可以简化季度分析时的逻辑。

  • 增强查询效率

通过使用日期维度表,数据仓库中的事实表可以使用日期维度表的主键(日期键 date_key)进行关联,从而减少在查询中对时间的复杂计算。例如,避免在每次查询时都使用 DATE_FORMAT 函数转换日期,而是直接关联维度表中的现成字段,提升查询效率。

  • 方便时间序列分析

日期维度表可以帮助快速进行时间序列分析,如趋势分析、环比分析、同比分析等。它为每个日期提供了连续的时间线,方便与事实表关联进行时间序列计算。

  • 支持特殊日的标记

日期维度表还可以扩展,加入一些自定义的特殊日标记,如节假日(元旦、春节等)或其他业务相关的重要日期,这样在分析时可以轻松区分平日和特殊日的业务表现。

  • 作为业务时间轴的基础

日期维度表通常作为其他维度表的基础,比如根据日期维度表中的季度信息生成季度维度表,根据月份生成月份维度表等。它是建立时间相关的业务逻辑的核心。

  • 统一时间标准

通过使用统一的日期维度表,数据仓库中的所有时间相关分析都可以基于同一日期集合,确保一致性。例如,所有按周、月或季度的分析,都可以从同一维度表中获取相关信息,避免由于日期计算的不同而导致的不一致性。

  • 易于维护和扩展

日期维度表通常是自动生成的,维护简单。如果需要扩展新的时间字段(如农历日期或其他时区的日期信息),也可以在日期维度表中直接扩展字段,保持数据仓库的灵活性。


日期维度表生成

创建日期维度表的表结构:

CREATE TABLE `dim_date` (
  `date` date NOT NULL COMMENT '完整日期 (作为主键)',
  `date_short` varchar(10) DEFAULT NULL COMMENT '短日期格式 (YY/MM/DD)',
  `date_medium` varchar(12) DEFAULT NULL COMMENT '中日期格式 (MMM DD, YYYY)',
  `date_long` varchar(20) DEFAULT NULL COMMENT ' 长日期格式 (MMMM DD, YYYY)',
  `date_full` varchar(30) DEFAULT NULL COMMENT ' 完整日期格式 (Weekday, Month DD, YYYY)',
  `day_in_year` int DEFAULT NULL COMMENT ' 一年中的第几天',
  `day_in_month` int DEFAULT NULL COMMENT ' 一月中的第几天',
  `day_name` varchar(10) DEFAULT NULL COMMENT ' 完整的星期几名称 (e.g., Monday)',
  `day_abbreviation` varchar(3) DEFAULT NULL COMMENT ' 星期几缩写 (e.g., Mon)',
  `day_abbreviation_zh` varchar(6) DEFAULT NULL COMMENT ' 星期几缩写 (e.g., 星期一,星期二)',
  `week_in_year` int DEFAULT NULL COMMENT ' 一年中的第几周',
  `week_in_month` int DEFAULT NULL COMMENT ' 一月中的第几周',
  `month_number` int DEFAULT NULL COMMENT ' 月份编号 (1-12)',
  `month_abbreviation` varchar(3) DEFAULT NULL COMMENT ' 月份缩写 (e.g., Jan)',
  `month_abbreviation_zh` varchar(3) DEFAULT NULL COMMENT ' 月份缩写 (e.g., 一月,二月)',
  `year2` varchar(2) DEFAULT NULL COMMENT ' 2位年份 (e.g., 23)',
  `year4` varchar(4) DEFAULT NULL COMMENT ' 4位年份 (e.g., 2023)',
  `quarter_name` varchar(6) DEFAULT NULL COMMENT ' 季度名称 (e.g., Q1)',
  `quarter_name_zh` varchar(6) DEFAULT NULL COMMENT ' 季度名称 (e.g., 第一季度,第二季度)',
  `quarter_number` int DEFAULT NULL COMMENT ' 季度编号 (1-4)',
  `is_first_day_in_week` tinyint(1) DEFAULT NULL COMMENT ' 是否为一周的第一天',
  `is_last_day_in_week` tinyint(1) DEFAULT NULL COMMENT ' 是否为一周的最后一天',
  `is_first_day_in_month` tinyint(1) DEFAULT NULL COMMENT ' 是否为一个月的第一天',
  `is_last_day_in_month` tinyint(1) DEFAULT NULL COMMENT ' 是否为一个月的最后一天',
  `year_quarter` varchar(7) DEFAULT NULL COMMENT ' 年度季度 (e.g., 2023-Q1)',
  `year_month_number` varchar(7) DEFAULT NULL COMMENT ' 年度月份编号 (e.g., 2023-01)',
  `year_month_abbreviation` varchar(8) DEFAULT NULL COMMENT ' 年度月份缩写 (e.g., 2023-Jan)',
  `date_key` int DEFAULT NULL COMMENT ' 日期键 (YYYYMMDD)',
  PRIMARY KEY (`date`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;

创建日期维度表存储过程:

CREATE PROCEDURE `fill_dim_date`(IN start_date DATE, IN end_date DATE)

begin
  
  DECLARE current_date1 DATE;
  DECLARE day_name_zh VARCHAR(6);
  DECLARE month_abbreviation_zh VARCHAR(3);
  DECLARE quarter_name_zh VARCHAR(6);

  SET current_date1 = start_date;

  WHILE current_date1 <= end_date DO

    -- 计算中文星期几
    CASE DAYOFWEEK(current_date1)
      WHEN 1 THEN SET day_name_zh = '星期日';
      WHEN 2 THEN SET day_name_zh = '星期一';
      WHEN 3 THEN SET day_name_zh = '星期二';
      WHEN 4 THEN SET day_name_zh = '星期三';
      WHEN 5 THEN SET day_name_zh = '星期四';
      WHEN 6 THEN SET day_name_zh = '星期五';
      WHEN 7 THEN SET day_name_zh = '星期六';
    END CASE;

    -- 计算中文月份缩写
    CASE MONTH(current_date1)
      WHEN 1 THEN SET month_abbreviation_zh = '一月';
      WHEN 2 THEN SET month_abbreviation_zh = '二月';
      WHEN 3 THEN SET month_abbreviation_zh = '三月';
      WHEN 4 THEN SET month_abbreviation_zh = '四月';
      WHEN 5 THEN SET month_abbreviation_zh = '五月';
      WHEN 6 THEN SET month_abbreviation_zh = '六月';
      WHEN 7 THEN SET month_abbreviation_zh = '七月';
      WHEN 8 THEN SET month_abbreviation_zh = '八月';
      WHEN 9 THEN SET month_abbreviation_zh = '九月';
      WHEN 10 THEN SET month_abbreviation_zh = '十月';
      WHEN 11 THEN SET month_abbreviation_zh = '十一月';
      WHEN 12 THEN SET month_abbreviation_zh = '十二月';
    END CASE;

    -- 计算中文季度名称
    CASE QUARTER(current_date1)
      WHEN 1 THEN SET quarter_name_zh = '第一季度';
      WHEN 2 THEN SET quarter_name_zh = '第二季度';
      WHEN 3 THEN SET quarter_name_zh = '第三季度';
      WHEN 4 THEN SET quarter_name_zh = '第四季度';
    END CASE;

    -- 插入日期数据
    INSERT INTO dim_date (
      `date`, 
      `date_short`, 
      `date_medium`, 
      `date_long`, 
      `date_full`, 
      `day_in_year`, 
      `day_in_month`, 
      `day_name`, 
      `day_abbreviation`, 
      `day_abbreviation_zh`, 
      `week_in_year`, 
      `week_in_month`, 
      `month_number`, 
      `month_abbreviation`, 
      `month_abbreviation_zh`, 
      `year2`, 
      `year4`, 
      `quarter_name`, 
      `quarter_name_zh`, 
      `quarter_number`, 
      `is_first_day_in_week`, 
      `is_last_day_in_week`, 
      `is_first_day_in_month`, 
      `is_last_day_in_month`, 
      `year_quarter`, 
      `year_month_number`, 
      `year_month_abbreviation`, 
      `date_key`
    ) VALUES (
      current_date1, 
      DATE_FORMAT(current_date1, '%y/%m/%d'),  -- 短日期格式
      DATE_FORMAT(current_date1, '%b %d, %Y'), -- 中日期格式
      DATE_FORMAT(current_date1, '%M %d, %Y'), -- 长日期格式
      DATE_FORMAT(current_date1, '%W, %M %d, %Y'), -- 完整日期格式
      DAYOFYEAR(current_date1),  -- 一年中的第几天
      DAY(current_date1),  -- 一月中的第几天
      DAYNAME(current_date1),  -- 完整星期几名称
      LEFT(DAYNAME(current_date1), 3),  -- 星期几缩写
      day_name_zh,  -- 中文星期几缩写
      WEEKOFYEAR(current_date1),  -- 一年中的第几周
      WEEK(current_date1, 5) - WEEK(DATE_SUB(current_date1, INTERVAL DAYOFMONTH(current_date1) - 1 DAY), 5) + 1, -- 一月中的第几周
      MONTH(current_date1),  -- 月份编号
      DATE_FORMAT(current_date1, '%b'), -- 月份缩写
      month_abbreviation_zh, -- 中文月份缩写
      DATE_FORMAT(current_date1, '%y'), -- 2位年份
      DATE_FORMAT(current_date1, '%Y'), -- 4位年份
      CONCAT('Q', QUARTER(current_date1)), -- 季度名称
      quarter_name_zh,  -- 中文季度名称
      QUARTER(current_date1),  -- 季度编号
      IF(DAYOFWEEK(current_date1) = 1, 1, 0), -- 是否为一周的第一天
      IF(DAYOFWEEK(current_date1) = 7, 1, 0), -- 是否为一周的最后一天
      IF(DAY(current_date1) = 1, 1, 0), -- 是否为一个月的第一天
      IF(LAST_DAY(current_date1) = current_date1, 1, 0), -- 是否为一个月的最后一天
      CONCAT(YEAR(current_date1), '-Q', QUARTER(current_date1)), -- 年度季度
      DATE_FORMAT(current_date1, '%Y-%m'), -- 年度月份编号
      DATE_FORMAT(current_date1, '%Y-%b'), -- 年度月份缩写
      DATE_FORMAT(current_date1, '%Y%m%d') -- 日期键
    );

    -- 将日期加1天

    SET current_date1 = DATE_ADD(current_date1, INTERVAL 1 DAY);
  END WHILE;
END
执行
call fill_dim_date('2024-01-01','2024-09-15')

技术点

设置全局变量 default_week_format

你可以通过设置 MySQL 的全局或会话变量 default_week_format 来更改默认的周计算方式,使得周一为一周的第一天。

SET @@global.default_week_format = 1;  -- 设置全局默认周格式,周一为一周的第一天
SET @@session.default_week_format = 1; -- 设置当前会话的默认周格式

此变量值 1 表示周一为一周的第一天。如果你需要在整个 MySQL 会话中使用周一作为一周的第一天,可以在会话开始时设置。  

相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
相关文章
|
2天前
|
关系型数据库 MySQL
mysql中单独获取已知日期的年月日其中之一
通过上述内容,您应该能够更好地在MySQL中处理和提取日期和时间信息,以满足各种业务需求。
15 5
|
1月前
|
关系型数据库 MySQL
Mysql 中日期比较大小的方法有哪些?
在 MySQL 中,可以通过多种方法比较日期的大小,包括使用比较运算符、NOW() 函数、DATEDIFF 函数和 DATE 函数。这些方法可以帮助你筛选出特定日期范围内的记录,确保日期格式一致以避免错误。
|
1月前
|
SQL NoSQL 关系型数据库
|
2月前
|
存储 关系型数据库 MySQL
mysql 8.0 时间维度表生成(可运行)
mysql 8.0 时间维度表生成(可运行)
51 0
|
2月前
|
关系型数据库 MySQL 数据处理
企业级应用 mysql 日期函数变量,干货已整理
本文详细介绍了如何在MySQL8.0中使用DATE_FORMAT函数进行日期格式的转换,包括当日、昨日及不同时间段的数据获取,并提供了实际的ETL应用场景和注意事项,有助于提升数据处理的灵活性和一致性。
48 0
|
5月前
|
消息中间件 关系型数据库 MySQL
实时计算 Flink版操作报错合集之运行mysql to doris pipeline时报错,该如何排查
在使用实时计算Flink版过程中,可能会遇到各种错误,了解这些错误的原因及解决方法对于高效排错至关重要。针对具体问题,查看Flink的日志是关键,它们通常会提供更详细的错误信息和堆栈跟踪,有助于定位问题。此外,Flink社区文档和官方论坛也是寻求帮助的好去处。以下是一些常见的操作报错及其可能的原因与解决策略。
|
4月前
|
SQL 关系型数据库 MySQL
MySQL运行在docker容器中会损失多少性能
MySQL运行在docker容器中会损失多少性能
|
5月前
|
存储 SQL Cloud Native
云原生数据仓库使用问题之运行MySQL命令发现中文内容变成了问号,该如何解决
阿里云AnalyticDB提供了全面的数据导入、查询分析、数据管理、运维监控等功能,并通过扩展功能支持与AI平台集成、跨地域复制与联邦查询等高级应用场景,为企业构建实时、高效、可扩展的数据仓库解决方案。以下是对AnalyticDB产品使用合集的概述,包括数据导入、查询分析、数据管理、运维监控、扩展功能等方面。
|
6月前
|
关系型数据库 MySQL 数据库
mysql之日期时间函数
SELECT SECOND('12:45:31'); -- 结果: 31 请注意,以上结果取决于实际查询执行的时间和日期。在实际的数据库操作中,通常会使用列名作为参数,而不是直接使用硬编码的日期或时间值。例如: SELECT YEAR(birthdate) FROM employees; 这将返回 employees 表中每位员工的 birthdate 列的年份。日期和时间函数在处理数据时非常有用,特别是当你需要对日期和时间进行操作或计算时。 ————————————————
47 0
|
6月前
|
关系型数据库 MySQL API
实时计算 Flink版操作报错合集之同步MySQL数据到另一个MySQL数据库,第一次同步后源表数据发生变化时目标表没有相应更新,且Web UI中看不到运行的任务,该怎么解决
在使用实时计算Flink版过程中,可能会遇到各种错误,了解这些错误的原因及解决方法对于高效排错至关重要。针对具体问题,查看Flink的日志是关键,它们通常会提供更详细的错误信息和堆栈跟踪,有助于定位问题。此外,Flink社区文档和官方论坛也是寻求帮助的好去处。以下是一些常见的操作报错及其可能的原因与解决策略。
199 0
下一篇
DataWorks