大家好!今天我想和大家分享一下我们在处理业务需求时遇到的一次“小插曲”。
故事的主角当然离不开那些让人又爱又恨的SQL语句。
1、一开始的简单思路
首先,业务需求是员工关怀——为每周过生日的员工一起准本个下午茶蛋糕,即查询本周生日员工的名单,这听起来挺简单对吧?我们想到的第一步,就是使用SQL语句来查询符合条件的员工。
于是我们很快想到了SQL函数 WEEKOFYEAR()
。像这样:
SELECT name
FROM user
WHERE WEEKOFYEAR(birthday) = WEEKOFYEAR(CURDATE());
这个思路看起来不错,但是随着我们开始测试,事情就变得有些不对劲了!
2、实际测试中的“惊喜”
为了确保我们不会漏掉任何一个过生日的员工,我们在数据库里插入了10万条假数据来进行测试。
用Navicat工具生成测试数据
今天5月30号,对于本周生日的每个员工都显得非常重要,但测试结果却比我们预期得更加“惊悚”。
今天的日期2024年05月30日
理论上,本周的日期范围应该是从5月27号到6月2号。可是,测试结果却不对。
测试结果:
测试显示我们查出来的日期范围是从5月24号到6月6号。
What?!这哪里对得上呢?
3、Bug的“根源”
查询 CHAT-GPT 发现了问题的根源——WEEKOFYEAR()
这个神奇的函数,它的作用是返回给定日期在一年中的第几周。也就是说,它其实把每个员工他们出生那年的第几周跟今年的第几周进行的对比,显然是不正确的!
4、解决方案的诞生
那么,既然知道了问题所在,解决它就是时间问题了。
我们需要的方法是将每个员工的生日月日与今年的年份拼接起来,然后进行周数对比。
这时,我们的大脑如打了鸡血般清醒,瞬间又充满了希望。
下面就是我们的聪明SQL,重新洗牌之后的成果:
SELECT name
FROM user
WHERE
WEEK(
DATE_FORMAT(CURDATE(), '%Y%m%d'), 1
) = WEEK(
STR_TO_DATE(
CONCAT(DATE_FORMAT(CURDATE(), '%Y'), DATE_FORMAT(birthday, '%m%d')),
'%Y%m%d'
), 1
);
这里我们用了 DATE_FORMAT()
和 STR_TO_DATE()
等函数,
把今年当前“年份”与员工生日的“月份”、“日期”拼接起来,
再 WEEK()
函数对比周数(指定周从星期一开始计算)。
WEEK()
是 MySQL 中的一个日期函数,用于返回给定日期的一年中的周数。它有不同的模式,可以根据不同的模式计算周数,周数范围通常在 0 到 53 之间。默认模式是
0
,即周从星期天开始,周范围是 0-53。也可指定模式 1 ,周从星期一开始,周范围是 0-53。
重新测试数据:
测试结果实现了精准命中,完美解决业务需求。
5、意想不到的收获
这个过程中,我们不仅解决了问题,还对SQL有了更深入的了解。
这样的小插曲也提醒我们,代码就像人生,表面看似简单,实际可能隐藏了很多细节,需要我们不断探究和钻研。
希望你们在处理业务需求时,少一些惊心动魄,更多是兴奋的“啊哈!原来如此!”时刻。
如果你们也有类似的有趣故事,欢迎分享哦!