Sql 语句小课堂6:使用开窗函数和系统表生成一个简单的日历

Sql 语句小课堂6:使用开窗函数和系统表生成一个简单的日历

额,这个部分是修改后追加的,因为质量分太低,所以水点内容,提一提质量分,嘿嘿。

系统表 spt_values

嗯,用来补全数据很常用的一个表,通常写作 master…spt_values,其中 type 为 p 的内容,有 0 到 2017 的连续整数,共2048个数字,对于数据补全缺失,可以结合 id 列或日期列之类的,补全数据的相关文章,可以参考《sqlserver 数据区间补全

CTE 表

一个可以用来生成或者建立临时数据的方便的方法,当然,也不仅仅可以这么做,同样可以参考老顾的其他文章《【新星计划】数据库 CTE 初识》或自行百度。

CSDN 文盲老顾的博客https://blog.csdn.net/superwfei
老顾的个人社区https://bbs.csdn.net/forums/bfba6c5031e64c13aa7c60eebe858a5f?category=10003&typeId=3364713

排名函数

首先了解下 sqlserver 的开窗函数,有 row_number,rank,dense_rank,都可以对行数据进行排序并附加序号,关于row_number就不细说了,本文使用 dense_rank

关于排名函数,可以自行百度一下,也可以看老顾的文章《【新星计划】数据库 排名函数 初识

日期函数

然后,我们在本文里复习一下日期函数的用法,dateadd,datediff,datepart

dateadd 用来对日期进行计算,比如前一天,后一天,前一小时后一小时之类的,当然,也可以前三十天,后一年之类的。

datediff 用来求两个日期数据的差,差的结果以指定的类型进行返回,比如日期差,分钟差,月份差之类的。

datepart 用来获取日期之间指定位置的数据,比如年、月、日、星期几之类的。

行转列

最后,使用行转列,完成日历的排布

行转列的时候,需要注意一点,如果出去需要转列的字段外,其他字段如果完全相同,则会合并成为同一行,如果所有其他列都不相同,则会每个数据占一行,如果部分相同,部分不同,则相同的合并为同一行,不同的则为多行,也就是本文日历实现的逻辑。

完整代码



declare @year int,@sd date,@ed date
-- 指定公历年份
set @year = 2021 
-- 获得当年的第一天与次年的第一天
select @sd = CONVERT(varchar,@year)+'-1-1',@ed=CONVERT(varchar,@year+1)+'-1-1'

;with t as (
	-- 先将所有日期补全出来
	select dateadd(d,number,@sd) as d 
	from master..spt_values
	where type='p'
	and number<DATEDIFF(D,@sd,@ed)
),t1 as (
	-- 取得每个日期所属的月份和星期数以及每周的第几天,需要注意,如果设置了星期天归属设置,输出内容可能有差异
	-- 使用 dense_rank 排名函数,对每个月的所有日期使用同一个排名,dense_rank与rank的区别在于一个连续,一个非连续
	select dense_rank() over(order by convert(varchar(6),d,112)) as m,DATEPART(week,d) w,DATEPART(weekday,d) as wd,DATEPART(day,d) as d 
	from t
)
select CONVERT(varchar,m)+'月' as 月份,'第'+convert(varchar,w)+'周' 周目
	,[1] 周日,[2] 周一,[3] 周二,[4] 周三,[5] 周四,[6] 周五,[7] 周六 
from t1 a
pivot(
	max(d) for wd in ([1],[2],[3],[4],[5],[6],[7])
)p

月份     周目       周日        周一        周二        周三        周四        周五        周六
------ -------- ----------- ----------- ----------- ----------- ----------- ----------- -----------
1月     第1NULL        NULL        NULL        NULL        NULL        1           2
1月     第23           4           5           6           7           8           9
1月     第310          11          12          13          14          15          16
1月     第417          18          19          20          21          22          23
1月     第524          25          26          27          28          29          30
1月     第631          NULL        NULL        NULL        NULL        NULL        NULL
2月     第6NULL        1           2           3           4           5           6
2月     第77           8           9           10          11          12          13
2月     第814          15          16          17          18          19          20
2月     第921          22          23          24          25          26          27
2月     第1028          NULL        NULL        NULL        NULL        NULL        NULL
3月     第10NULL        1           2           3           4           5           6
3月     第117           8           9           10          11          12          13
3月     第1214          15          16          17          18          19          20
3月     第1321          22          23          24          25          26          27
3月     第1428          29          30          31          NULL        NULL        NULL
4月     第14NULL        NULL        NULL        NULL        1           2           3
4月     第154           5           6           7           8           9           10
4月     第1611          12          13          14          15          16          17
4月     第1718          19          20          21          22          23          24
4月     第1825          26          27          28          29          30          NULL
5月     第18NULL        NULL        NULL        NULL        NULL        NULL        1
5月     第192           3           4           5           6           7           8
5月     第209           10          11          12          13          14          15
5月     第2116          17          18          19          20          21          22
5月     第2223          24          25          26          27          28          29
5月     第2330          31          NULL        NULL        NULL        NULL        NULL
6月     第23NULL        NULL        1           2           3           4           5
6月     第246           7           8           9           10          11          12
6月     第2513          14          15          16          17          18          19
6月     第2620          21          22          23          24          25          26
6月     第2727          28          29          30          NULL        NULL        NULL
7月     第27NULL        NULL        NULL        NULL        1           2           3
7月     第284           5           6           7           8           9           10
7月     第2911          12          13          14          15          16          17
7月     第3018          19          20          21          22          23          24
7月     第3125          26          27          28          29          30          31
8月     第321           2           3           4           5           6           7
8月     第338           9           10          11          12          13          14
8月     第3415          16          17          18          19          20          21
8月     第3522          23          24          25          26          27          28
8月     第3629          30          31          NULL        NULL        NULL        NULL
9月     第36NULL        NULL        NULL        1           2           3           4
9月     第375           6           7           8           9           10          11
9月     第3812          13          14          15          16          17          18
9月     第3919          20          21          22          23          24          25
9月     第4026          27          28          29          30          NULL        NULL
10月    第40NULL        NULL        NULL        NULL        NULL        1           2
10月    第413           4           5           6           7           8           9
10月    第4210          11          12          13          14          15          16
10月    第4317          18          19          20          21          22          23
10月    第4424          25          26          27          28          29          30
10月    第4531          NULL        NULL        NULL        NULL        NULL        NULL
11月    第45NULL        1           2           3           4           5           6
11月    第467           8           9           10          11          12          13
11月    第4714          15          16          17          18          19          20
11月    第4821          22          23          24          25          26          27
11月    第4928          29          30          NULL        NULL        NULL        NULL
12月    第49NULL        NULL        NULL        1           2           3           4
12月    第505           6           7           8           9           10          11
12月    第5112          13          14          15          16          17          18
12月    第5219          20          21          22          23          24          25
12月    第5326          27          28          29          30          31          NULL

(63 行受影响)
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 7
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

文盲老顾

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值