Comment déterminer si une plage de dates se produit tout moment dans une autre plage de dates?

StackOverflow https://stackoverflow.com/questions/730722

  •  06-09-2019
  •  | 
  •  

Question

J'ai une table d'événements qui spécifie une plage de dates avec des champs de start_date et end_date. J'ai une autre plage de dates, spécifié dans le code, qui définit la semaine en cours comme « week_start » et « week_end ».

Je voudrais interroger tous les événements de la semaine. Les cas semblent être:

  • L'événement commence et se termine dans la semaine
  • commence l'événement avant la semaine, mais se termine dans la semaine
  • commence l'événement dans la semaine, mais se termine après la semaine
  • commence l'événement avant la semaine et se termine également après la semaine
  • Les événements qui ne résident à l'intérieur, ni se chevauchent la semaine du tout sont ignorés

Je tente de trouver une requête qui peut traiter tous ces cas. Jusqu'à présent, je ne l'ai été en mesure d'obtenir des cas qui gèrent les chevauchements de semaine, ou des événements qui sont entièrement internes; Pour l'essentiel, trop de dossiers, ou pas du tout.

Était-ce utile?

La solution

(event.start BETWEEN week.start AND week.end)
OR
(week.start BETWEEN event.start AND event.end)

En mots simples, soit une semaine commence au cours de l'événement, ou un événement commence au cours de la semaine.

Vérifions-le:

  

commence et se termine l'événement dans la semaine

L'événement commence au cours de la semaine.

  

commence l'événement avant la semaine, mais se termine dans la semaine

La semaine commence au cours de l'événement.

  

commence l'événement dans la semaine, mais se termine après la semaine

L'événement commence au cours de la semaine.

  

commence l'événement avant la semaine et se termine également après la semaine

La semaine commence au cours de l'événement.

Notez que BETWEEN dans les expressions ci-dessus est utilisé seulement pour des raisons de concision.

stricte expression ressemble à ceci:

(event.start >= week.start AND event.start < week.end)
OR
(week.start >= event.start AND week.start < event.end)

, à condition que week.end est un week.start + INTERVAL 7 DAY.

. e. si vous la semaine commence de Sun, 0:00:00, il devrait se terminer sur next Sun, 0:00:00 (pas Sat, 0:00:00)

Cette expression semble plus complexe que celui qui est couramment utilisé:

event.start < week.end AND event.end > week.start

, mais le premier est plus efficace et l'indice convivial.

Voir ces articles dans mon blog pour les comparaisons de performance:

Autres conseils

Vous pouvez écrire votre condition comme ceci:

start_date <= week_end AND end_date >= week_start

Edit: cela suppose start_date <= date_fin et week_start <= week_end (sont correctement commandés) et vous donne les meilleures performances sur la plupart des implémentations de db en raison de ne pas utiliser OR (qui, sur certaines bases de données peuvent créer des problèmes de performance)

Edit2. Cette solution résout également le problème des événements qui commencent avant l'intervalle et se termine après l'intervalle

+1 pour la pop Catalin, mais hélas je n'ai pas le privilège de vote.

La condition que vous voulez limiter est juste la façon standard pour exprimer l'opérateur « OVERLAPS » Allen.

mise en garde SQL supplémentaires:. Si date_fin est annulable, assurez-vous de traiter dans ces colonnes nulls comme « la fin du temps »

mise en garde fonctionnelle supplémentaire:. Assurez-vous d'adapter l'utilisation de « <= » contre « < » pour savoir si oui ou non les périodes enregistrées comprennent la date de fin ou non

...

where start_date >= week_start and end_date <= week_end
where start_date <= week_start and end_date >= week_start and end_date <= week_end
where start_date >= week_start and start_date <= week_end and end_date > week_end
where start_date < week_start and end_date > week_end

(sens2> = start1) && (start2 <= end1) Je pense que renverrait vrai pour toutes les plages de dates entrecroisés.

J'ai trouvé une discussion sur ce que je trouvé utile.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top