Ok, jag kom på det och det var ganska enkelt, i princip på var och en av LEFT JOIN
Jag var tvungen att filtrera bort startdatumet efter de parametrar som angavs.
Jag var också tvungen att filtrera efter om ledigheten var godkänd, en Approved_DateTime
och Approved_By
fältet var ifyllt om det godkändes. Även beräkningen av varaktigheten var lite fel under vissa omständigheter. Så min lagrade procedur ser nu ut så här:
DELIMITER $$
USE `test`$$
DROP PROCEDURE IF EXISTS `GetLeaveDates`$$
CREATE DEFINER=`root`@`%` PROCEDURE `GetLeaveDates`(pEmpID INT, pDateFrom DATETIME, pDateTo DATETIME, pApproved BOOLEAN)
BEGIN
SELECT
DATE_FORMAT(a.start_date,'%d/%m/%y') AS start,
CASE WHEN a.am_pm = 1 THEN "AM"
WHEN a.am_pm = 2 THEN "PM"
ELSE "" END AS start_am_pm,
DATE_FORMAT(CASE WHEN pDateTo > MIN(c.start_date) THEN
MIN(c.start_date)
ELSE
pDateTo
END, '%d/%m/%y') AS end,
CASE WHEN c.am_pm = 1 THEN "AM"
WHEN c.am_pm = 2 THEN "PM"
ELSE "" END AS end_am_pm,
CASE WHEN a.am_pm = 0 THEN
CASE WHEN c.am_pm = 0 OR c.am_pm = 2 THEN
DATEDIFF(MIN(c.start_date),a.start_date)+1
WHEN c.am_pm = 1 THEN
DATEDIFF(MIN(c.start_date),a.start_date)+0.5
END
WHEN a.am_pm = 1 THEN
CASE WHEN c.am_pm = 0 OR c.am_pm = 2 THEN
DATEDIFF(MIN(c.start_date),a.start_date)+1
WHEN c.am_pm = 1 THEN
DATEDIFF(MIN(c.start_date),a.start_date)+0.5
END
WHEN a.am_pm = 2 THEN
CASE WHEN c.am_pm = 0 OR c.am_pm = 2 THEN
DATEDIFF(MIN(c.start_date),a.start_date)+0.5
WHEN c.am_pm = 1 THEN
DATEDIFF(MIN(c.start_date),a.start_date)
END
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) AND ISNULL(b.approved_datetime) <> pApproved AND b.start_date BETWEEN pDateFrom AND pDateTo
LEFT JOIN t AS c ON a.employee_id=c.employee_id AND a.start_date <= c.start_date AND ISNULL(c.approved_datetime) <> pApproved AND c.start_date BETWEEN pDateFrom AND pDateTo
LEFT JOIN t AS d ON c.employee_id=d.employee_id AND c.start_date = ADDDATE(d.start_date,-1) AND ISNULL(d.approved_datetime) <> pApproved AND d.start_date BETWEEN pDateFrom AND pDateTo
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
AND ISNULL(a.approved_datetime) <> pApproved
AND a.start_date BETWEEN pDateFrom AND pDateTo
GROUP BY a.employee_id, a.start_date
; END$$
DELIMITER ;