직원을 퇴사시키는 데이터베이스가 있습니다. 직원이 퇴근 할 때마다 새 레코드가 데이터베이스에 입력됩니다. 내가 성취하고자하는 것은 누군가가 종업원 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
주 : 10과 12 모두 반 일이기 때문에 첫 번째 기간은 위의 2 11 일은 꽉 찼습니다.
어쨌든. 시작 날짜가 직원이 떠날 날짜가 아니라면 예상했던대로 정확하게 쿼리가 작동합니다. 예를 들어 위의 예제에서 날짜를 10 일, 11 일 또는 12 일로 설정하면 해당 행이 제거됩니다. 지정된 날짜 사이의 날짜를 계산해야합니다.
은 현재 (직원 9999과 2011-09-01에 2011-08-11 날짜)하는 방법을 보여줍니다: 유사
employee_id | Start | start_am_pm | End | end_am_pm | Duration
9999 | 2011-09-01 | | 2011-09-01 | | 1
날짜에 일어나고했지만, 난 고정 것을 얻었다. 유사한 접근 방식이 시작 날짜에 작동하지 않았습니다. 아래 내 저장 프로 시저입니다. 기본적으로
LEFT JOIN
의 각 난에 전달 된 매개 변수에 의해 시작 날짜에서 필터링 기준으로했다
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