MySQL 找每个月最后一个星期五 -- 函数定义与使用

   日期:2020-10-12     浏览:130    评论:0    
核心提示:数据库作业有一道题是这样子的:有一张名叫emp的表记录员工信息,其中有如下字段 HIREDATE 表示员工被雇用的日期:然后问题是这样的:q7. Show details of employee hiredates and the date of their first payday. (Paydays occur on the last Friday of each month) (plus their names)意思就是每个月的最后一个周五是发工资的日子,要我们输出他们领到第一桶金的日

数据库作业有一道题是这样子的:

有一张名叫emp的表记录员工信息,其中有如下字段 HIREDATE 表示员工被雇用的日期:

然后问题是这样的:

q7.	Show details of employee hiredates and the date of their first payday. 
(Paydays occur on the last Friday of each month) 
(plus their names)

意思就是每个月的最后一个周五是发工资的日子,要我们输出他们领到第一桶金的日子。(这里其实是计算当月payday,不考虑hiredate超过payday的情况)

那么怎么通过一个日期计算出当月的最后一个周五呢?我们用最暴力的方法,直接迭代计算:

思路:

  1. LAST_DAY 函数找当月最后一天 x
  2. 日期 x 逐天减少
  3. 直到 x 等于周五,即是最后一个周五

代码:

DELIMITER $$	# 结束符由 ; 改为 $$ 。因为函数中间需要用到 ; 号
DROp FUNCTION IF EXISTS last_friday $$	# 删除之前定义的函数 last_friday 
CREATE FUNCTION last_friday (dt DATE) RETURNS DATE	# 定义函数 last_friday 有一个DATE类的形参 dt,返回DATE对象
BEGIN
	DECLARE last DATE;	# 临时变量 last
	SET last=LAST_DAY(dt);	# last=dt的最后一天
	WHILE DATE_FORMAT(last, "%W")!="Friday" DO	# 不断判断是否为周五
		SET last=DATE_SUB(last, interval 1 day);	# 迭代减少天数
	END WHILE;
	RETURN last;	# 返回结果
END $$
DELIMITER ;	# 结束符由 $$ 改为 ; 号 

# 不带注释 ↓

DELIMITER $$
DROP FUNCTION IF EXISTS last_friday $$
CREATE FUNCTION last_friday (dt DATE) RETURNS DATE
BEGIN
	DECLARE last DATE;
	SET last=LAST_DAY(dt);
	WHILE DATE_FORMAT(last, "%W")!="Friday" DO
		SET last=DATE_SUB(last, interval 1 day);
	END WHILE;
	RETURN last;
END $$
DELIMITER ;

然后我们就可以通过 last_friday 函数进行查询:

SELECT ENAME, HIREDATE, last_friday(HIREDATE) FROM emp;

结果:

然后下一题:

q8.	Refine your answer to 7 such that it works 
even if an employee is hired after the last Friday of the month 
(cf Martin)

意思是有一些员工是在payday之后入职的,比如:


那么我们应该找下一个payday。思路也很简单,通过 if 语句进行判断即可。

  1. 如果当月payday大于入职日期hiredate,返回当月payday
  2. 如果当月payday小于入职日期hiredate,返回下个月的payday

我们首先编写一个函数next_friday,计算下个月的payday

DELIMITER $$
DROP FUNCTION IF EXISTS next_friday $$
CREATE FUNCTION next_friday (dt DATE) RETURNS DATE
BEGIN
	DECLARE last DATE;
	SET last=LAST_DAY(DATE_ADD(dt, interval 1 month));
	WHILE DATE_FORMAT(last, "%W")!="Friday" DO
		SET last=DATE_SUB(last, interval 1 day);
	END WHILE;
	RETURN last;
END $$
DELIMITER ;

这个函数和 last_friday 没啥区别,就是计算下个月而已:

随后我们修改 last_friday ,最后返回时加一个判断即可:

DELIMITER $$
DROP FUNCTION IF EXISTS last_friday $$
CREATE FUNCTION last_friday (dt DATE) RETURNS DATE
BEGIN
	DECLARE last DATE;
	SET last=LAST_DAY(dt);
	WHILE DATE_FORMAT(last, "%W")!="Friday" DO
		SET last=DATE_SUB(last, interval 1 day);
	END WHILE;
	RETURN IF(last>dt, last, next_friday(dt));
END $$
DELIMITER ;

注意这个 if 表达式即可:

if(expr, case1, case2)
if(条件, 情况1, 情况2)

随后再次运行查询:

舒服了

 
打赏
 本文转载自:网络 
所有权利归属于原作者,如文章来源标示错误或侵犯了您的权利请联系微信13520258486
更多>最近资讯中心
更多>最新资讯中心
0相关评论

推荐图文
推荐资讯中心
点击排行
最新信息
新手指南
采购商服务
供应商服务
交易安全
关注我们
手机网站:
新浪微博:
微信关注:

13520258486

周一至周五 9:00-18:00
(其他时间联系在线客服)

24小时在线客服