【发布时间】:2011-08-11 13:53:24
【问题描述】:
我有一个存储员工离职的数据库。对于员工休假的每一天,都会将新记录输入到数据库中。我想要实现的是让某人输入员工 ID 和日期范围,并且对于每个缺勤期都会返回一条记录,说明日期、日期、持续时间以及是上午还是下午(半天)。
它应该看起来像(对于员工 9999 和日期 2011-08-08 到 2011-09-01):
employee_id | Start | start_am_pm | End | end_am_pm | Duration
9999 | 2011-08-10 | PM | 2011-08-12 | AM | 2
9999 | 2011-09-01 | | 2011-09-01 | | 1
注意:上面的第一个持续时间是 2,因为第 10 天和第 12 天都是半天,而第 11 天是完整的。
无论如何。如果 From 日期不是员工休假的日期,我的查询完全符合我的预期。例如,在上面的示例中,如果我将起始日期设置为 10 日、11 日或 12 日,它会删除该行。它应该计算指定日期之间的天数。
当前显示方式(员工 9999 和日期 2011-08-11 至 2011-09-01):
employee_id | Start | start_am_pm | End | end_am_pm | Duration
9999 | 2011-09-01 | | 2011-09-01 | | 1
To date 也发生了类似的情况,但我已经解决了。类似的方法不适用于 From 日期。下面是我的存储过程。
DELIMITER $$
USE `test`$$
DROP PROCEDURE IF EXISTS `GetLeaveDates`$$
CREATE DEFINER=`root`@`%` PROCEDURE `GetLeaveDates`(pEmpID INT, pDateFrom DATETIME, pDateTo DATETIME)
BEGIN
SELECT
a.start_date,
CASE WHEN a.am_pm = 1 THEN "AM"
WHEN a.am_pm = 2 THEN "PM"
ELSE "" END AS start_am_pm,
CASE WHEN pDateTo > MIN(c.start_date) THEN
MIN(c.start_date)
ELSE
pDateTo
END AS End,
CASE WHEN c.am_pm = 1 THEN "AM"
WHEN c.am_pm = 2 THEN "PM"
ELSE "" END AS start_am_pm,
CASE WHEN a.am_pm = 0 AND c.am_pm = 0 THEN
DATEDIFF(MIN(c.start_date),a.start_date)+1
WHEN (a.am_pm = 0 AND c.am_pm <> 0) OR (c.am_pm = 0 AND a.am_pm <> 0) THEN
DATEDIFF(MIN(c.start_date),a.start_date)+0.5
WHEN a.am_pm <> 0 AND c.am_pm <> 0 THEN
DATEDIFF(MIN(c.start_date),a.start_date)
END
AS Duration
FROM t AS a
LEFT JOIN t AS b ON a.employee_id=b.employee_id AND a.start_date = ADDDATE(b.start_date,1)
LEFT JOIN t AS c ON a.employee_id=c.employee_id AND a.start_date <= c.start_date
LEFT JOIN t AS d ON c.employee_id=d.employee_id AND c.start_date = ADDDATE(d.start_date,-1)
WHERE b.start_date IS NULL AND c.start_date IS NOT NULL AND d.start_date IS NULL
AND a.EMPLOYEE_ID = pEmpID
AND a.START_DATE BETWEEN pDateFrom AND pDateTo
GROUP BY a.employee_id, a.start_date
; END$$
DELIMITER ;
【问题讨论】:
-
坦白说,你的存储过程标准很高。但是,我想建议更改
Start,start_am_pm,End,end_am_pm的数据类型,您应该存储为 unix_timestamp,其中2011-08-10|PM= unix_timestamp('2011-08-10 12:00:00')`,带有时间戳,您可以轻松地进行范围选择等
标签: mysql