244 votes

Est-ce que le "entre" de MS SQL Server inclut les limites de la plage ?

Par exemple, peut

SELECT foo
FROM bar
WHERE foo BETWEEN 5 AND 10

sélectionner 5 et 10 ou ils sont exclus de la plage ?

266voto

DJ. Points 10596

L'opérateur BETWEEN est inclusif.

De Livres en ligne :

BETWEEN renvoie VRAI si la valeur de expression_test est supérieure ou égale à la valeur de l'expression begin_expression et inférieure ou égale à la valeur de l'expression_finale.

Mise en garde concernant les dates et heures

NB : Avec les DateTimes, vous devez faire attention ; si seule une date est donnée, la valeur est prise à minuit ce jour-là ; pour éviter de manquer des heures dans votre date de fin, ou de répéter la capture des données du jour suivant à minuit dans plusieurs plages, votre date de fin doit être 3 millisecondes avant minuit le jour suivant votre date de début. 3 millisecondes, car si la valeur est inférieure, elle sera arrondie à minuit le jour suivant.

Par exemple, pour obtenir toutes les valeurs du mois de juin 2016, vous devez exécuter :

where myDateTime between '20160601' and DATEADD(millisecond, -3, '20160701')

c'est-à-dire

where myDateTime between '20160601 00:00:00.000' and '20160630 23:59:59.997'

datetime2 et datetimeoffset

En soustrayant 3 ms d'une date, vous risquez de manquer des lignes dans la fenêtre de 3 ms. La solution correcte est aussi la plus simple :

where myDateTime >= '20160601' AND myDateTime < '20160701'

12 votes

Lorsque vous utilisez BETWEEN pour filtrer les dates entre deux dates, vous pouvez également convertir la date-heure en date, par exemple : where CONVERT(DATE, MyDate) BETWEEN '2017-09-01' and '2017-09-30' Cette approche rend l'élément temporel de la date-heure non pertinent.

2 votes

Veillez à ne pas essayer de soustraire 3 ms d'une date ; vous manquerez des éléments de ces 3 ms. Et vous ne voulez pas non plus CONVERT a datetime à un date car cela rendrait les index inutiles. Utilisez la méthode standard WHERE OrderDate >= '20160601' AND OrderDate < '20160701' . Veillez également à utiliser yyyymmdd comme yyyy-mm-dd dépend de la locale, et sera mal interprété en fonction de la langue de votre serveur. mdy, dmy, ymd, ydm, myd, and dym réglage.

260voto

BradC Points 18833

Oui, mais attention à l'utilisation de l'intervalle pour les dates.

BETWEEN '20090101' AND '20090131'

est réellement interprété comme étant 12 heures du matin, ou

BETWEEN '20090101 00:00:00' AND '20090131 00:00:00'

Ainsi, tout ce qui s'est produit pendant la journée du 31 janvier sera omis. Dans ce cas, vous devrez utiliser :

myDate >= '20090101 00:00:00' AND myDate < '20090201 00:00:00'  --CORRECT!

o

BETWEEN '20090101 00:00:00' AND '20090131 23:59:59' --WRONG! (see update!)

UPDATE : Il est tout à fait possible d'avoir des enregistrements créés dans cette dernière seconde de la journée, avec une date aussi tardive que 20090101 23:59:59.997 ! !

Pour cette raison, le BETWEEN (firstday) AND (lastday 23:59:59) n'est pas recommandée.

Utilisez le myDate >= (firstday) AND myDate < (Lastday+1) à la place.

Bon article sur cette question ici .

1 votes

Problèmes similaires avec les chaînes de caractères WHERE col BETWEEN 'a' AND 'z' exclura la plupart des rangées z par exemple.

8 votes

Ce point est juste bien sûr, mais ne devrait pas être surprenant si vous travaillez avec des dates. C'est analogue au fait de signaler que BETWEEN 5 AND 10 n'inclut pas 10.2 ...

4 votes

CAST de la datetime en tant que DATE fonctionnerait : CAST(DATE_TIME_COL AS DATE) BETWEEN '01/01/2009' AND '01/31/2009' .

16voto

Ryan Rodemoyer Points 1798

Exemple concret à partir de SQL Server 2008.

Données sources :

ID    Start
1     2010-04-30 00:00:01.000
2     2010-04-02 00:00:00.000
3     2010-05-01 00:00:00.000
4     2010-07-31 00:00:00.000

Une requête :

SELECT
    *
FROM
    tbl
WHERE
    Start BETWEEN '2010-04-01 00:00:00' AND '2010-05-01 00:00:00'

Résultats :

ID    Start
1     2010-04-30 00:00:01.000
2     2010-04-02 00:00:00.000

alt text

0 votes

Je n'ai pas eu votre réponse, pour être honnête. Peut-être que mon fournisseur d'accès Internet a caché votre capture d'écran si vous en avez posté une.

3 votes

Pourquoi la ligne avec ID = 3 exclus ? Son Start est égale à la valeur BETWEEN valeur de la limite supérieure, et BETWEEN est un intervalle inclusif, et non un intervalle exclusif à limite supérieure.

0 votes

Une meilleure réponse avec des résultats.

13voto

Shaun Points 71

Si vous avez atteint ce niveau, et que vous ne voulez pas vraiment essayer de gérer l'ajout d'un jour en code, alors laissez le DB le faire

myDate >= '20090101 00:00:00' AND myDate < DATEADD(day,1,'20090101 00:00:00')

Si vous incluez l'heure, assurez-vous qu'il s'agit de minuit. Sinon, vous pouvez simplement omettre l'heure :

myDate >= '20090101' AND myDate < DATEADD(day,1,'20090101')

et ne pas s'en inquiéter.

12voto

Russ Cam Points 58168

ENTRE (Transact-SQL)

Spécifie un( n ) ( inclusivement ) à tester.

test_expression [ NOT ] BETWEEN begin_expression AND end_expression

Arguments

test_expression

Est l'expression à tester dans l'intervalle défini par begin_expression et end_expression. test_expression doit être du même type de données que begin_expression et end_expression.

NOT

Spécifie que le résultat du prédicat doit être nié.

begin_expression

Est une expression valide. begin_expression doit être du même type que test_expression. type de données que test_expression et end_expression.

end_expression

Est une expression valide. end_expression doit être du même type de données que type de données que test_expression et begin_expression.

AND

Agit comme un espace réservé qui indique que l'expression_test doit être dans l'intervalle indiqué par begin_expression et end_expression.

Remarques

Pour spécifier une plage exclusive, utilisez les fonctions supérieur à (>) et inférieur à (<). Si l'une des entrées de la fonction BETWEEN ou NOT BETWEEN est NULL, le résultat est UNKNOWN. NULL, le résultat est UNKNOWN.

Valeur du résultat

BETWEEN renvoie VRAI si la valeur de expression_test est supérieure ou égale à la valeur de l'expression begin_expression et inférieure ou égale à la valeur de l'expression_finale.

NOT BETWEEN renvoie VRAI si la valeur de test_expression est inférieure à la valeur de begin_expression ou supérieure à à la valeur de end_expression.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X