Ce tableau est utilisé pour stocker des sessions (événements):
CREATE TABLE session (
id int(11) NOT NULL AUTO_INCREMENT
, start_date date
, end_date date
);
INSERT INTO session
(start_date, end_date)
VALUES
("2010-01-01", "2010-01-10")
, ("2010-01-20", "2010-01-30")
, ("2010-02-01", "2010-02-15")
;
Nous ne voulons pas avoir de conflit entre les gammes.
Disons que nous devons insérer une nouvelle session de 2010-01-05 à 2010-01-25.
Nous aimerions connaître la (les) session (s) en conflit.
Voici ma requête:
SELECT *
FROM session
WHERE "2010-01-05" BETWEEN start_date AND end_date
OR "2010-01-25" BETWEEN start_date AND end_date
OR "2010-01-05" >= start_date AND "2010-01-25" <= end_date
;
Voici le résultat:
+----+------------+------------+
| id | start_date | end_date |
+----+------------+------------+
| 1 | 2010-01-01 | 2010-01-10 |
| 2 | 2010-01-20 | 2010-01-30 |
+----+------------+------------+
Y a-t-il une meilleure façon de l'obtenir?
J'ai eu une telle requête avec une application de calendrier que j'ai écrit une fois. Je pense avoir utilisé quelque chose comme ceci:
... WHERE new_start < existing_end
AND new_end > existing_start;
UPDATE Ceci devrait fonctionner ((ns, ne, es, ee) = (new_start, new_end, existing_start, existing_end)):
Voici un violon
SELECT * FROM tbl WHERE
existing_start BETWEEN $newStart AND $newEnd OR
existing_end BETWEEN $newStart AND $newEnd OR
$newStart BETWEEN existing_start AND existing_end
if (!empty($result))
throw new Exception('We have overlapping')
Ces 3 lignes de clauses sql couvrent les 4 cas de chevauchement requis.
La réponse de Lamy est bonne, mais vous pouvez l'optimiser un peu plus.
SELECT * FROM tbl WHERE
existing_start BETWEEN $newSTart AND $newEnd OR
$newStart BETWEEN existing_start AND existing_end
Cela intercepte les quatre scénarios où les plages se chevauchent et exclut les deux où ils ne le font pas.
J'avais affronté le même problème. Mon problème était d'arrêter de réserver entre une série de dates bloquées. Par exemple, la réservation est bloquée pour une propriété entre le 2 et le 7 mai. Je devais trouver tout type de date de chevauchement pour détecter et arrêter la réservation. Ma solution est similaire à LordJavac.
SELECT * FROM ib_master_blocked_dates WHERE venue_id=$venue_id AND
(
(mbd_from_date BETWEEN '$from_date' AND '$to_date')
OR
(mbd_to_date BETWEEN '$from_date' AND '$to_date')
OR
('$from_date' BETWEEN mbd_from_date AND mbd_to_date)
OR
('$to_date' BETWEEN mbd_from_date AND mbd_to_date)
)
*mbd=master_blocked_dates
Faites-moi savoir si cela ne fonctionne pas.
Étant donné deux intervalles comme (s1, e1) et (s2, e2) avec s1 <e1 et s2 <e2
Vous pouvez calculer le chevauchement comme ceci:
SELECT
s1, e1, s2, e2,
ABS(e1-s1) as len1,
ABS(e2-s2) as len2,
GREATEST(LEAST(e1, e2) - GREATEST(s1, s2), 0)>0 as overlaps,
GREATEST(LEAST(e1, e2) - GREATEST(s1, s2), 0) as overlap_length
FROM test_intervals
Cela fonctionnera également si un intervalle est dans l’autre.
Récemment, je me débattais avec le même problème et m’arrivais à la fin avec cette étape facile (cela peut ne pas être une bonne approche ou consommer de la mémoire)
SELECT * FROM duty_register WHERE employee = '2' AND (
(
duty_start_date BETWEEN {$start_date} AND {$end_date}
OR
duty_end_date BETWEEN {$start_date} AND {$end_date}
)
OR
(
{$start_date} BETWEEN duty_start_date AND duty_end_date
OR
{$end_date} BETWEEN duty_start_date AND duty_end_date)
);
Cela m'a aidé à trouver les entrées avec des plages de dates qui se chevauchent.
J'espère que ça aide quelqu'un.