我有一個存儲員工離開的數據庫。對於每一天員工休假,新的記錄被輸入到數據庫中。我想要達到的目的是讓某人輸入員工編號和日期範圍,並且在每個缺勤期間記錄都會返回,記錄日期,日期和持續時間,以及是否爲上午或下午(半天)。獲取連續日期的收集
它應該是這個樣子(員工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日已滿。
無論如何。如果發件日期不是員工留下的日期,則我的查詢完全按照我的預期工作。例如,在上面的例子中,如果我將起始日期設置爲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
類似的是與發生在日期,但我得到了修復。類似的方法不適用於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')',帶時間戳,您可以輕鬆地進行範圍選擇等 – ajreal