Dans MySQL, si j'ai une liste de plages de dates (début de plage et fin de plage). par exemple
10/06/1983 to 14/06/1983
15/07/1983 to 16/07/1983
18/07/1983 to 18/07/1983
Et je veux vérifier si une autre plage de dates contient UNE des plages déjà dans la liste, comment puis-je faire cela?
par exemple
06/06/1983 to 18/06/1983 = IN LIST
10/06/1983 to 11/06/1983 = IN LIST
14/07/1983 to 14/07/1983 = NOT IN LIST
Réponses:
C'est un problème classique, et c'est en fait plus facile si vous inversez la logique.
Laisse moi te donner un exemple.
Je vais publier une période ici, et toutes les différentes variations d'autres périodes qui se chevauchent d'une manière ou d'une autre.
par contre, permettez-moi de poster tous ceux qui ne se chevauchent pas:
Donc, si vous réduisez simplement la comparaison à:
alors vous trouverez toutes celles qui ne se chevauchent pas, puis vous trouverez toutes les périodes non correspondantes.
Pour votre dernier exemple NOT IN LIST, vous pouvez voir qu'il correspond à ces deux règles.
Vous devrez décider si les périodes suivantes sont à l'intérieur ou à l'extérieur de vos plages:
Si votre table a des colonnes appelées range_end et range_start, voici un SQL simple pour récupérer toutes les lignes correspondantes:
Notez le PAS là-dedans. Puisque les deux règles simples trouvent toutes les lignes non correspondantes , un simple NOT l'inversera pour dire: si ce n'est pas l'une des lignes non correspondantes, elle doit être l'une des lignes correspondantes .
Appliquez ici une logique d'inversion simple pour vous débarrasser du NOT et vous vous retrouverez avec:
la source
En prenant votre exemple de plage du 06/06/1983 au 18/06/1983 et en supposant que vous ayez des colonnes appelées début et fin pour vos plages, vous pouvez utiliser une clause comme celle-ci
c.-à-d. vérifiez que le début de votre plage de test est avant la fin de la plage de base de données, et que la fin de votre plage de test est après ou au début de la plage de base de données.
la source
Si votre SGBDR prend en charge la fonction OVERLAP (), cela devient trivial - pas besoin de solutions maison. (Dans Oracle, cela fonctionne apparemment mais n'est pas documenté).
la source
Dans vos résultats attendus, vous dites
06/06/1983 au 18/06/1983 = EN LISTE
Cependant, cette période ne contient ni n'est contenue dans aucune des périodes de votre tableau (pas de liste!) De périodes. Il chevauche cependant la période du 10/06/1983 au 14/06/1983.
Vous pouvez trouver le livre Snodgrass ( http://www.cs.arizona.edu/people/rts/tdbbook.pdf ) utile: il est antérieur à mysql mais le concept du temps n'a pas changé ;-)
la source
J'ai créé une fonction pour résoudre ce problème dans MySQL. Convertissez simplement les dates en secondes avant utilisation.
la source
Regardez dans l'exemple suivant. Cela vous sera utile.
la source
Essayez ceci sur MS SQL
la source
la source
Une autre méthode à l'aide de l'instruction BETWEEN SQL
Périodes incluses:
Périodes exclues:
la source
la source