Question

Dans SQL Server 2000 et 2005:

  • quelle est la différence entre ces deux clauses WHERE ?
  • lequel dois-je utiliser dans 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'

(Édition: le deuxième Eventdate manquait à l'origine, donc la requête était syntaxiquement incorrecte)

Était-ce utile?

La solution

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 seconde condition.)

Autres conseils

Ce sont les mêmes.

Une chose à laquelle il faut faire 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

( cela correspondrait à < = 20/10/2009 00: 00: 00.000 )

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

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

De plus, un autre piège est que les bornes inférieure et supérieure doivent être spécifiées dans le bon ordre (c.-à-d. entre bas et haut ).

Généralement, 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.

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

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

Toutefois, les valeurs temporelles fractionnaires peuvent être à l'origine de problèmes avec une plage fermée (supérieure ou égale et inférieure ou égale ), par opposition à une plage semi-ouverte (supérieure ou égale). inférieur à ) 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 */

Puisque BETWEEN ne fonctionne pas pendant des intervalles semi-ouverts, j'examine toujours attentivement toute requête date / heure l'utilisant, car c'est probablement une erreur.

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.

Il y a peut-être une différence spécifique au SGBDR dont je ne suis pas au courant, mais je ne le crois pas vraiment.

J'ai une légère préférence pour BETWEEN , car le lecteur comprend immédiatement 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 comporte à la fois une transactiondate et un transitiondate , si je lis

transactiondate between ...

Je sais immédiatement que les deux extrémités du test sont contre ce champ.

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.

De plus, 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 requêtes 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 un BETWEEN , bien sûr, ce sera une erreur de syntaxe qui sera rapidement corrigée.

Logiquement, il n’ya aucune différence. En termes de performances, il n’ya généralement aucune différence entre les systèmes de gestion de base de données et les SGBD.

Voir ceci excellent article de Aaron Bertrand expliquant pourquoi vous devriez modifier le format de votre chaîne et comment les valeurs limites sont traitées dans les requêtes de plage de dates.

Clause de non-responsabilité: 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é 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)

  

A ENTRE MINBOUND ET MAXBOUND

Cas 3: Deux comparaisons dans un ordre éclairé (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 le jeu de données.

Cependant, le cas 3 peut considérablement améliorer les temps d’exécution. En particulier, si vous travaillez avec un ensemble de données volumineux et que vous avez des connaissances heuristiques pour savoir si A a plus de chances d'être supérieur à MaxBound ou inférieur à < strong> MinBound : vous pouvez améliorer sensiblement les temps d'exécution en utilisant le scénario 3 et en ordonnant les comparaisons en conséquence.

Un de mes cas d'utilisation consiste à interroger un ensemble de données historiques volumineux avec des dates non indexées pour les enregistrements d'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 du jeu de données, de la complexité de la requête et du nombre d’enregistrements filtrés par la première comparaison.

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