Ok l'ho capito ed è stato abbastanza semplice, praticamente su ciascuno dei LEFT JOIN
Ho dovuto filtrare la data di inizio in base ai parametri passati.
Ho anche dovuto filtrare in base al fatto che il congedo fosse approvato, un Approved_DateTime
e Approved_By
campo dove compilato se è stato approvato. Anche il calcolo della durata è stato un po' sbagliato in alcune circostanze. Quindi la mia procedura memorizzata ora è simile a:
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 ;