一枚小产品的学习记录
在做sql练习题时了解到的新函数,做个简要的记录,因非技术人员(专业人士),可能会存在一定的局限性,若有不严谨的地方,请指正。
在日常的业务统计需求中,可能会有类似查询“某一日是今年第几周“的需求。mysql提供了week(date,mode)函数来满足此种需求。
其中2个参数分别为:
date:date是要获取周数的日期,比如2020-01-04,记得要加引号,若不加引号也不会报错,会返回null。
mode: mode是计算逻辑的参数,用于确定周数计算的逻辑。看了众多资料,统一认定mode的参数为0到7这8个参数,也就是8种计算逻辑。
但是我尝试了8-15也不会报错,且返回了合理的值,经个人多次验证及推测,底层会将mode对8取模。最终的mode参数为mod(mode,8) 。备注:本人的mysql为8.0.21版本。
mode可不写,其默认参数为:0, 可通过设置全局变量来修改该值。
至于为何要有mode这个参数呢,我想主要是为了符合各种统计逻辑的需求,因为按照不同的计算逻辑,特定的某一天会属于不同的周。
举2个最简单的例子:
1;有些人把周日当成一周的第一天,有些人把周一当成一周的第一天。
2:有些人把新年的第一个周日到第二个周日算作新年的第一周,不会去考虑其他因素。
有些人则认为从1月1日起到下一个周日的天数若大于3天则这几天算为一周,若小于3天则这几天算为第0周,或者这
几天算作去年的最后一周。
所以可以看出因为计算逻辑的不统一,会造成统计误差。
因此mysql提供了8种计算逻辑,来满足各种统计需求。
下表为各种模式的具体解释:
image.png
那么我以2021年1月2日举下例子:
日历如下:
image.png
测试如下:
SELECT WEEK('2021-01-02',0) #运行结果:0
SELECT WEEK('2021-01-02',1) #运行结果:0
SELECT WEEK('2021-01-02',2) #运行结果:52
SELECT WEEK('2021-01-02',3) #运行结果:53
当模式为0时,对照模式表可以得知其计算逻辑是:把星期日当做一周的第一天,且第一周是以2021年的第一个星期日开始的,且在2021年的第一个星期日前那些属于2021年的天数都归为第0周。而2021年1月2日是2021年第一个星期日之前的日期,所以返回的结果是0。
当模式为1时,对照模式表可以得知其计算逻辑是:把星期一当做一周的第一天,且1月1日到本年第一个周一的天数超过3天,则认定这几天处于本年的第1周,若天数没超过3天(不足4天),则认定这几天处于本年的第0周。而2021年1月1日到第一个周一(2021年1月4日)只有3天(即1月1日、1月2日、1月3日)。所以认定这几天属于2021年的第0周,所以返回的结果为0。
当模式为2时,对照模式表可以得知其计算逻辑是:把星期日当做一周的第一天,且第一周是以2021年的第一个星期日开始的,前面的日期都算作上年度的最后一周(而模式0则是把这几天算作为第0周)。而2021年1月2日是2021年第一个星期日之前日期,所以认定这几天属于2020年的最后一周(2020年的第52周),所以返回的结果为52。备注也就是说2020年的日期也是默认使用2这种模式来计算的。
其他的模式就不做详细说明了,大家自己去验证吧~