如何编写SQL查询休假天数最多的员工(附表结构及示例语句)
分析你的SQL查询问题 & 最优实现方案
首先得指出你当前语句里的几个关键问题,再根据需求给出更可靠的写法:
原语句的核心问题
- 日期计算逻辑错误:
Startdate - Enddate在绝大多数数据库里都会得到负数(因为休假结束日期肯定晚于开始日期),而且这种写法不是标准的天数计算方式,不同数据库有专门的日期差函数(比如MySQL的DATEDIFF、SQL Server的DATEDIFF(day, ...))。另外如果需要包含休假的首尾两天(比如1号到3号算3天),还需要额外+1,否则会少算1天。 - 需求理解偏差:你的语句是在找单条休假时长最长的员工,但问题描述里的“休假天数最多”更可能指的是员工累计的总休假天数最多,这两个逻辑完全不同。
- 连接写法不够规范:用逗号连接两张表是旧版SQL的写法,推荐用
INNER JOIN的显式连接,可读性和维护性更好。
分场景的最优实现方案
场景1:查询累计总休假天数最多的员工
这应该是你更需要的场景,先计算每个员工的总休假天数,再筛选出总天数最高的员工:
MySQL版本
SELECT emp.*, leave_totals.total_leave_days FROM Employee24 emp INNER JOIN ( -- 子查询:计算每个员工的累计休假天数 SELECT EMPLOYEEID, SUM(DATEDIFF(ENDDATE, STARTDATE) + 1) AS total_leave_days -- +1是为了包含休假的首尾两天,若业务不需要可去掉 FROM Leave25 GROUP BY EMPLOYEEID -- 筛选出总天数等于所有员工中最大值的记录 HAVING total_leave_days = ( SELECT MAX(total) FROM ( SELECT SUM(DATEDIFF(ENDDATE, STARTDATE) + 1) AS total FROM Leave25 GROUP BY EMPLOYEEID ) AS sub_total ) ) AS leave_totals ON emp.EMPLOYEEID = leave_totals.EMPLOYEEID;
SQL Server版本
把日期计算换成DATEDIFF(day, STARTDATE, ENDDATE)即可:
SELECT emp.*, leave_totals.total_leave_days FROM Employee24 emp INNER JOIN ( SELECT EMPLOYEEID, SUM(DATEDIFF(day, STARTDATE, ENDDATE) + 1) AS total_leave_days FROM Leave25 GROUP BY EMPLOYEEID HAVING total_leave_days = ( SELECT MAX(total) FROM ( SELECT SUM(DATEDIFF(day, STARTDATE, ENDDATE) + 1) AS total FROM Leave25 GROUP BY EMPLOYEEID ) AS sub_total ) ) AS leave_totals ON emp.EMPLOYEEID = leave_totals.EMPLOYEEID;
场景2:查询单条休假时长最长的员工
如果你的需求确实是找单条休假最长的员工,修正后的语句如下:
MySQL版本
SELECT emp.*, DATEDIFF(l.ENDDATE, l.STARTDATE) + 1 AS single_leave_days FROM Leave25 l INNER JOIN Employee24 emp ON emp.EMPLOYEEID = l.EMPLOYEEID WHERE DATEDIFF(l.ENDDATE, l.STARTDATE) + 1 = ( SELECT MAX(DATEDIFF(ENDDATE, STARTDATE) + 1) FROM Leave25 );
额外说明
- 如果你的数据库是Oracle,日期差可以用
TRUNC(ENDDATE) - TRUNC(STARTDATE)来计算天数(同样需要+1的话就加)。 - 以上写法都考虑了多个员工并列第一的情况,会把所有总天数/单条天数最多的员工都查出来,而不是只返回一条。
内容的提问来源于stack exchange,提问作者user2147357
相关产品推荐
相关产品推荐

