Si j'exécute une requête avec une between
clause, cela semble exclure la valeur de fin.
Par exemple:
select * from person where dob between '2011-01-01' and '2011-01-31'
Ceci obtient tous les résultats avec dob
du «2011-01-01» au «2011-01-30»; sauter les enregistrements où dob
est «2011-01-31». Quelqu'un peut-il expliquer pourquoi cette requête se comporte de cette façon et comment je pourrais la modifier pour inclure des enregistrements où se dob
trouve «2011-01-31»? (sans ajouter 1 à la date de fin car il a été sélectionné par les utilisateurs.)
BETWEEN
Inclut les deux valeurs. J'aiMySQL Server 5.7
sur Windows 10.Réponses:
Le champ a
dob
probablement une composante temporelle.Pour le tronquer:
la source
CAST(dob AS DATE)
vous, vous pouvez utiliser le plus succinctDATE(dob)
.>=
et<
au lieu debetween
.dob BETWEEN '2011-01-01 00:00:00' AND '2011-01-31 23:59:59
. En effet,DATE(dob)
il faut calculer une valeur pour chaque ligne et ne peut utiliser aucun index sur ce champ.t > 23:59:59 and t < 24:00:00
. Pourquoi traiter du tout mal spécifiéBETWEEN
? Suivez plutôt les conseils et l' utilisation de David:WHERE dob >= '2011-01-01' AND dob < '2011-02-01'
. Meilleures performances, et cela fonctionne à chaque fois.À partir du manuel MySQL :
la source
Le problème est que 2011-01-31 est vraiment 2011-01-31 00:00:00. C'est le début de la journée. Tout pendant la journée n'est pas inclus.
la source
la source
2011-01-31 23:59:59
mais inclura celles jusqu'à2011-01-31 23:59:58
la dernière seconde de la journée n'est pas inclus. Cela pourrait être mineur mais quelqu'un en bénéficiera.23:59:59
dans le résultat. Donc, c'est dans les deux sens inclusif.dob
colonne est un horodatage avec une précision inférieure à la seconde, alors neBETWEEN
manquera pas les événements dans la dernière seconde de la journée à moins que «2011-02-01 00:00:00» ne soit utilisé à la place?2011-01-31 23:59:59.003
. L'utilisation de @nitrogen2011-02-01 000:00:00
inclura à tort l' heure zéro le 1er février .... C'est pourquoi>=
et<
devrait être utilisé à la place.Le champ que vous référencez dans votre requête est-il de type Date ou de type DateHeure ?
Une cause courante du comportement que vous décrivez est lorsque vous utilisez un type DateTime alors que vous devriez vraiment utiliser un type Date. Autrement dit, à moins que vous n'ayez vraiment besoin de savoir à quelle heure une personne est née, utilisez simplement le type Date.
La raison pour laquelle le dernier jour n'est pas inclus dans vos résultats est la façon dont la requête prend en compte la partie horaire des dates que vous n'avez pas spécifiées dans votre requête.
Autrement dit: votre requête est interprétée comme jusqu'à minuit entre le 30/01/2011 et le 31/01/2011, mais les données peuvent avoir une valeur plus tard dans la journée, le 31/01/2011.
Suggestion: remplacez le champ par le type Date s'il s'agit d'un type DateHeure.
la source
Salut cette requête fonctionne pour moi,
la source
De manière surprenante, ces conversions sont des solutions à de nombreux problèmes dans MySQL.
la source
Définissez la date supérieure à date + 1 jour, donc dans votre cas, définissez-la sur 2011-02-01.
la source
BETWEEN
il faut l'ignorer; mais>=
et<
devrait être utilisé à la place.Vous pouvez exécuter la requête en tant que:
comme d'autres l'ont souligné, si vos dates sont codées en dur.
En revanche, si la date est dans une autre table, vous pouvez ajouter un jour et soustraire une seconde (si les dates sont enregistrées sans la seconde / heure), comme:
Évitez de faire des lancers sur les
dob
champs (comme dans la réponse acceptée), car cela peut causer d'énormes problèmes de performances (comme ne pas pouvoir utiliser un index sur ledob
terrain, en supposant qu'il y en ait un). Le plan d'exécution peut changer deusing index condition
àusing where
si vous faites quelque chose commeDATE(dob)
ouCAST(dob AS DATE)
, alors soyez prudent!la source
Dans MySql, les valeurs sont inclusives, donc lorsque vous essayez de passer entre '2011-01-01' et '2011-01-31'
il comprendra de
2011-01-01 00:00:00
jusqu'à2011-01-31 00:00:00
donc rien fait dans 2011-01-31 depuis son temps devrait passer de2011-01-31 00:00:00 ~ 2011-01-31 23:59:59
Pour la limite supérieure, vous pouvez changer pour
2011-02-01
alors il obtiendra toutes les données jusqu'à2011-01-31 23:59:59
la source