Mysql
 sql >> Base de Dados >  >> RDS >> Mysql

Obtendo coleções de datas consecutivas


Ok, eu descobri e foi bem simples, basicamente em cada um dos LEFT JOIN Eu tive que filtrar a data de início pelos parâmetros passados.

Também tive que filtrar se a licença foi aprovada, um Approved_DateTime e Approved_By campo onde preenchido caso tenha sido aprovado. Além disso, o cálculo da duração estava um pouco errado em algumas circunstâncias. Então, meu procedimento armazenado agora se parece com:
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 ;