Tengo una tabla con los siguientes datos.
CREATE TABLE DiscountFormula ( id int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY , dateFrom date , dateUntil date ); INSERT INTO DiscountFormula (dateFrom, dateUntil) VALUES ("2020-06-01", "2020-06-10") , ("2020-06-03", "2020-06-13") , ("2020-06-25", "2020-06-29") , ("2020-07-01", "2020-07-01") , ("2020-07-03", "2020-07-03") ;
id dateFrom dateUtil ==== ======== ======== 1 2020-06-01 2020-06-10 2 2020-06-03 2020-06-13 3 2020-06-25 2020-06-29 4 2020-07-01 2020-07-01 5 2020-07-03 2020-07-03
Como puede ver, las identificaciones 1
y 2
se superponen en un rango de fechas. Quiero crear una consulta para detectar si algún rango de fechas se superpone en la tabla. Lo que significa que si el count > 0
tiene datos superpuestos, puedo lanzar un mensaje de alerta. Lo que he intentado, pero parece que no funciona.
SELECT * #count(*) as TOTAL FROM DiscountFormula A JOIN DiscountFormula B ON (A.dateFrom >= B.dateFrom AND A.dateFrom <= B.dateUntil) OR (A.dateUntil >= B.dateFrom AND A.dateUntil <= B.dateUntil)
Su fórmula para detectar rangos superpuestos está ligeramente equivocada. Debería ser esto:
WHERE A.dateFrom < B.dateUntil AND A.dateUntil > B.dateFrom AND A.id <> B.id
Consulta actualizada:
SELECT COUNT(*) FROM DiscountFormula A INNER JOIN DiscountFormula B ON A.dateFrom < B.dateUntil AND A.dateUntil > B.dateFrom AND A.id <> B.id;
Recomendaría usar un máximo acumulativo:
select count(*) from (select df.*, max(df.dateuntil) over (order by df.datefrom rows between unbounded preceding and 1 preceding ) as prev_dateuntil from DiscountFormula df ) df where prev_dateuntil > datefrom;
Esto debería ser mucho más rápido que una autounión. Si count(*)
es 0
, entonces no hay superposiciones.
En realidad, creo que un lag()
es suficiente para este problema:
select count(*) from (select df.*, lag(df.dateuntil) over (order by df.datefrom) as prev_dateuntil from DiscountFormula df ) df where prev_dateuntil > datefrom;