相关文章推荐
重感情的单车  ·  Spark SQL常用函数 ...·  1 周前    · 
神勇威武的杨桃  ·  【新技术】圆锥角膜治疗新方法—角膜交联术-哈 ...·  8 月前    · 
悲伤的针织衫  ·  $巨化股份(SH600160)$ 1、制冷剂 ...·  11 月前    · 
痴情的帽子  ·  捷尼赛思GV70EV:宝马iX3同级,双电机 ...·  1 年前    · 
独立的草稿本  ·  2023-2024财年悉尼房产政策- 知乎·  1 年前    · 
暴走的荒野  ·  超能战衣完整小说 - 抖音·  1 年前    · 
Code  ›  SQL 打印一个月的日历开发者社区
date 社区功能 select date函数
https://cloud.tencent.com/developer/article/1664409
愉快的匕首
1 年前
白日梦想家

SQL 打印一个月的日历

腾讯云
开发者社区
文档 建议反馈 控制台
首页
学习
活动
专区
工具
TVP
最新优惠活动
文章/答案/技术大牛
发布
首页
学习
活动
专区
工具
TVP 最新优惠活动
返回腾讯云官网
白日梦想家
首页
学习
活动
专区
工具
TVP 最新优惠活动
返回腾讯云官网
社区首页 > 专栏 > SQL 打印一个月的日历

SQL 打印一个月的日历

作者头像
白日梦想家
发布 于 2020-07-20 10:04:30
1.2K 0
发布 于 2020-07-20 10:04:30
举报
文章被收录于专栏: SQL实现 SQL实现

今天,我们用 SQL 做一件有趣的东西:打印一个月的日历。

下图是我从电脑上截的本月的日历。

接下来我们在 MYSQL 上输出这个效果。

大致的思路如下:

  1. 获取指定日期所在月份的第一天的日期和该月的天数;
  2. 生成该月的所有日期集合;
  3. 格式化输出。

1 获取月初第一天和该月的天数

在 MySQL 里面,实现日期的加减可以使用 DATE_ADD(date,INTERVAL expr unit) / DATE_SUB(date,INTERVAL expr unit) 函数。

另外,还可以用 LAST_DAY(date) 获取最后一天的日期。

# 设置日期变量
SET @someday:=CURDATE();
# 获取该月第一天
SELECT DATE_ADD(@someday,INTERVAL - DAY(@someday) + 1 DAY) 
# 获取该月的天数
SELECT DAY(LAST_DAY(@someday))

2 生成所在月的日期集合

MySQL 暂时没有提供像 Oracle 的 start with connect by prior 一样的语法,用它可以递归生成一批简单的测试数据集,但我们可以借助数字辅助表实现该功能。

我们用到了数字辅助表 t_seq,t_seq 的表结构很简单,只有一个整数字段,里面存储了从 1 - 1000 的自然数。

t_seq 的表结构

CREATE TABLE `t_seq` (
  `id` int(10) unsigned NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8

生成一个月的所有日期的集合

SELECT 
    WEEK(day_m, 1) AS wk,
    WEEKDAY(day_m) AS wkday,
    DAY(day_m) AS day_index,
    day_m AS full_day 
    (SELECT 
      DATE_ADD(first_day, INTERVAL id - 1 DAY) AS day_m 
      (SELECT 
        DATE_ADD(
          @someday,
          INTERVAL - DAY(@someday) + 1 DAY
        ) AS first_day) a,
      t_seq t 
    WHERE t.id <= DAY(LAST_DAY(@someday))

3 格式化日历

我们在第 2 步生成的数据集只有一列,要输出日历的效果,还得做一层行转列操作:根据每周做分组,星期一到星期天作为列,将一列转成四行七列或者五行七列的格式。

MySQL 提供了 WEEK(date[,mode]) 函数获取每周的编号,传入不同的 mode 参数返回的数据会不一样。

Mode

First day of week

Range

Week 1 is the first week …

0

Sunday

0-53

with a Sunday in this year

1

Monday

0-53

with 4 or more days this year

2

Sunday

1-53

with a Sunday in this year

3

Monday

1-53

with 4 or more days this year

4

Sunday

0-53

with 4 or more days this year

5

Monday

0-53

with a Monday in this year

6

Sunday

1-53

with 4 or more days this year

7

Monday

1-53

with a Monday in this year

由于我们把星期一看作一周的第一天,所以 mode 只能选 1 和 5。

完整的 SQL 实现如下:

SET @someday := CURDATE();
SELECT 
  MAX(IF(wkday = 0, day_index, '')) AS '一',
  MAX(IF(wkday = 1, day_index, '')) AS '二',
  MAX(IF(wkday = 2, day_index, '')) AS '三',
  MAX(IF(wkday = 3, day_index, '')) AS '四',
  MAX(IF(wkday = 4, day_index, '')) AS '五',
  MAX(IF(wkday = 5, day_index, '')) AS '六',
  MAX(IF(wkday = 6, day_index, '')) AS '日' 
  (SELECT 
    WEEK(day_m, 1) AS wk,
    WEEKDAY(day_m) AS wkday,
    DAY(day_m) AS day_index,
    day_m AS full_day 
    (SELECT 
      DATE_ADD(first_day, INTERVAL id - 1 DAY) AS day_m 
      (SELECT 
        DATE_ADD(
          @someday,
          INTERVAL - DAY(@someday) + 1 DAY
 
推荐文章
重感情的单车  ·  Spark SQL常用函数 函数分类及其简介_sparksql常用函数
1 周前
神勇威武的杨桃  ·  【新技术】圆锥角膜治疗新方法—角膜交联术-哈医大一院眼科医院
8 月前
悲伤的针织衫  ·  $巨化股份(SH600160)$ 1、制冷剂,又称雪种、氟利昂,相当于空调的血液。R22制冷剂曾一统空调行业数十年,但由... - 雪球
11 月前
痴情的帽子  ·  捷尼赛思GV70EV:宝马iX3同级,双电机四驱,700牛·米,38.58万起|新车|宝马ix3|新能源汽车|捷尼赛思gv70ev_网易订阅
1 年前
独立的草稿本  ·  2023-2024财年悉尼房产政策- 知乎
1 年前
暴走的荒野  ·  超能战衣完整小说 - 抖音
1 年前
今天看啥   ·   Py中国   ·   codingpro   ·   小百科   ·   link之家   ·   卧龙AI搜索
删除内容请联系邮箱 2879853325@qq.com
Code - 代码工具平台
© 2024 ~ 沪ICP备11025650号