web-dev-qa-db-fra.com

SQL: ENTRE vs <= et> =

Dans SQL Server 2000 et 2005:

  • quelle est la différence entre ces deux clauses WHERE?
  • lequel dois-je utiliser sur quels scénarios?

Requête 1:

SELECT EventId, EventName
FROM EventMaster
WHERE EventDate BETWEEN '10/15/2009' AND '10/18/2009'

Requête 2:

SELECT EventId, EventName
FROM EventMaster
WHERE EventDate >='10/15/2009'
  AND EventDate <='10/18/2009'

(Edit: le second Eventdate manquait à l'origine, donc la requête était syntaxiquement incorrecte)

92
Shyju

Ils sont identiques: BETWEEN est un raccourci pour la syntaxe la plus longue de la question. 

Utilisez une autre syntaxe plus longue où BETWEEN ne fonctionne pas, par exemple.

Select EventId,EventName from EventMaster
where EventDate >= '10/15/2009' and EventDate < '10/18/2009'

(Notez < plutôt que <= dans la deuxième condition.)

97
Tony Andrews

Ce sont les mêmes.

Attention, si vous utilisez ceci contre un DATETIME, le match pour la date de fin sera le début de la journée:

<= 20/10/2009

n'est pas la même chose que:

<= 20/10/2009 23:59:59

(il serait correspond à <= 20/10/2009 00:00:00.000)

31
Irfy

Bien que BETWEEN soit facile à lire et à gérer, je recommande rarement son utilisation car il s’agit d’un intervalle fermé et, comme indiqué précédemment, cela peut poser un problème avec les dates, même sans composante temporelle.

Par exemple, lorsqu’il s’agit de données mensuelles, il est souvent courant de comparer les dates BETWEEN first AND last, mais en pratique, il est généralement plus facile d’écrire dt >= first AND dt < next-first (ce qui résout également le problème du temps), car déterminer last est généralement un pas plus long que next-first (par soustraire un jour).

En outre, un autre piège est que les limites inférieure et supérieure doivent être spécifiées dans le ordre correct (c'est-à-dire BETWEEN low AND high).

12
Cade Roux

En règle générale, il n'y a pas de différence - le mot clé BETWEEN n'est pas pris en charge sur toutes les plateformes de SGBDR, mais s'il l'est, les deux requêtes doivent être identiques.

Comme ils sont identiques, il n'y a pas vraiment de distinction en termes de vitesse ou autre chose - utilisez celui qui vous semble le plus naturel.

4
marc_s

Comme mentionné par @marc_s, @Cloud, et al. ils sont fondamentalement les mêmes pour une gamme fermée.

Cependant, toute valeur temporelle fractionnée peut causer des problèmes avec une plage fermée (supérieure ou égale et moins ou égale ) par opposition à une plage semi-ouverte (supérieure ou égale et inférieure à ) avec une valeur finale après le dernier instant possible.

Donc, pour éviter que la requête ne soit réécrite comme suit:

SELECT EventId, EventName
  FROM EventMaster
 WHERE (EventDate >= '2009-10-15' AND
        EventDate <  '2009-10-19')    /* <<<== 19th, not 18th */

Étant donné que BETWEEN ne fonctionne pas pendant des intervalles semi-ouverts, j’examine toujours de près toute requête date/heure l’utilisant, car c’est probablement une erreur.

4
devstuff

Je pense que la seule différence est la quantité de sucre syntaxique sur chaque requête. BETWEEN est juste une façon astucieuse de dire exactement la même chose que la deuxième requête.

Je ne suis pas au courant de certaines différences spécifiques au SGBDR, mais je ne le crois pas vraiment.

3
pyrocumulus

J'ai une légère préférence pour BETWEEN car cela indique immédiatement au lecteur que vous vérifiez un champ pour une plage . Cela est particulièrement vrai si vous avez des noms de champs similaires dans votre table.

Si, par exemple, notre table a à la fois une transactiondate et une transitiondate, si je lis

transactiondate between ...

Je sais immédiatement que les deux bouts du test sont contre ce seul domaine.

Si je lis

transactiondate>='2009-04-17' and transactiondate<='2009-04-22'

Je dois prendre un moment supplémentaire pour m'assurer que les deux champs sont identiques.

En outre, lorsqu'une requête est modifiée au fil du temps, un programmeur négligent peut séparer les deux champs. J'ai vu beaucoup de questions qui disent quelque chose comme

where transactiondate>='2009-04-17'
  and salestype='A'
  and customernumber=customer.idnumber
  and transactiondate<='2009-04-22'

S'ils essaient cela avec une BETWEEN, bien sûr, ce sera une erreur de syntaxe qui sera corrigée rapidement.

2
Jay

Logiquement, il n'y a pas de différence du tout .. En termes de performances, il n'y a généralement aucune différence entre la plupart des SGBD.

2
mjv

Voir cet excellent article de blog de Aaron Bertrand sur la raison pour laquelle vous devez modifier votre format de chaîne et sur la manière dont les valeurs limites sont gérées dans les requêtes de plage de dates.

2
Andy Jones

Disclaimer: Tout ce qui est écrit ci-dessous n'est qu'anecdotique et tiré directement de mon expérience personnelle. Tous ceux qui se sentent prêts à mener une analyse plus rigoureuse sur le plan empirique sont les bienvenus pour voter à la machine si je le suis. Je suis également conscient du fait que SQL est un langage déclaratif et que vous n'êtes pas censé devoir prendre en compte le traitement de votre code lorsque vous l'écrivez, mais parce que j'apprécie mon temps, je le fais.

Il existe une infinité d'énoncés logiquement équivalents, mais j'en considèrerai trois (ish).

Cas 1: Deux comparaisons dans un ordre standard (ordre d'évaluation fixé)

A> = MinBound ET A <= MaxBound 

Cas 2: Sucre syntaxique (l'ordre d'évaluation n'est pas choisi par l'auteur)

UN ENTRE MinBound ET MaxBound

Cas 3: Deux comparaisons dans un ordre instruit (ordre d'évaluation choisi au moment de l'écriture)

A> = MinBound ET A> = MaxBound

Ou

A> = MaxBound ET A> = MinBound

D'après mon expérience, les cas 1 et 2 ne présentent pas de différences de performances cohérentes ou notables car ils ignorent les ensembles de données. 

Cependant, le cas 3 peut considérablement améliorer les temps d'exécution. Plus précisément, si vous travaillez avec un ensemble de données volumineux et que vous avez des connaissances heuristiques sur le fait queAest plus susceptible d'être supérieur au MaxBound ou inférieur au MinBound vous pouvez améliorer sensiblement les temps d'exécution en utilisant le cas 3 et en ordonnant les comparaisons en conséquence.

Un cas d'utilisation que j'ai est d'interroger un grand ensemble de données historiques avec des dates non indexées pour les enregistrements dans un intervalle spécifique. Lors de l'écriture de la requête, j'aurai une bonne idée de l'existence éventuelle de davantage de données AVANT l'intervalle spécifié ou APRÈS l'intervalle spécifié, et je peux ordonner mes comparaisons en conséquence. Les délais d'exécution ont été réduits de moitié, en fonction de la taille de l'ensemble de données, de la complexité de la requête et du nombre d'enregistrements filtrés par la première comparaison.

0
LanchPad