QUESTION: Pourquoi SQL est-il compris entre?
RÉPONSE: Les concepteurs de langage SQL ayant pris une mauvaise décision de conception, ils n’ont pas réussi à fournir une syntaxe permettant aux développeurs de spécifier laquelle des 4 variantes de BETWEEN (fermée, semi-ouverte à gauche, semi-ouverte à droite ou ouverte). ) ils préfèrent.
RECOMMANDATION: À moins que / jusqu'à ce que la norme SQL ne soit modifiée, n'utilisez pas BETWEEN pour les dates / heures. Prenez plutôt l’habitude de coder les comparaisons de plages DATE en tant que conditions indépendantes des limites de début et de fin de votre plage BETWEEN. Ceci est un peu détaillé, mais vous laissera des conditions d’écriture intuitives (donc moins susceptibles d’être boguées) et claires pour les optimiseurs de base de données, ce qui permettra de déterminer les plans d’exécution optimaux et d’utiliser les index.
Par exemple, si votre requête accepte une spécification de jour en entrée et doit renvoyer tous les enregistrements tombés à cette date, vous devez coder comme suit:
WHERE DATE_FIELD >= :dt AND DATE_FIELD < :dt+1
Essayer d'écrire la logique à l'aide de BETWEEN, de problèmes de performances et / ou de code erroné. Trois faux pas communs:
1) WHERE DATE_FIELD BETWEEN :dt AND :dt+1
Il s’agit presque certainement d’un bogue: l’utilisateur ne s'attend à voir que les enregistrements correspondant à une date donnée. Pourtant, un jour se terminera avec un rapport contenant des enregistrements à partir de midi le jour suivant.
2) WHERE TRUNC(DATE_FIELD) = :dt
Donne la bonne réponse, mais appliquer la fonction à DATE_FIELD rendra la plupart des index / statistiques inutiles (bien que parfois les administrateurs de bases de données essaient de l'aider en ajoutant des index basés sur les fonctions aux champs de date, tout en consommant toujours plus d'heures de travail et d'espace disque et en augmentant le temps de traitement du stérilet opérations sur la table)
3) WHERE EVENT_DATE BETWEEN :dt AND :dt + 1-1/24/60/60
Tom Kyte, extraordinaire gourou d’Oracle, recommande cette solution peu élégante (IMO). Fonctionne très bien jusqu'à ce que vous passiez toute la journée à trouver ce "1-1 / 24/06/60" dans une requête qui donne des résultats incomplets ... ou jusqu'à ce que vous l'utilisiez accidentellement sur un champ TIMESTAMP. De plus, c'est un peu propriétaire; compatible avec le type de données DATE d’Oracle (qui suit au second), mais doit être ajusté à la précision DATE / TIME de différents produits de base de données.
SOLUTION: demandez au comité SQL ANSI d'améliorer les spécifications de langage SQL en modifiant la syntaxe BETWEEN afin de prendre en charge la spécification d'alternatives à la valeur par défaut CLOSED / INCLUSIVE. Quelque chose comme ça ferait l'affaire:
expr1 ENTRE Expr2 [ INCL [USIVE] | EXCL [USIVE]] ET expr3 [ INCL [USIVE] | EXCL [USIVE]]
Considérez comme il est facile d’exprimer WHERE DATE_FIELD BETWEEN :dt INCLUSIVE AND :dt+1 EXCLUSIVE
(ou tout simplement WHERE DATE_FIELD BETWEEN :dt AND :dt+1 EXCL
)
Peut-être que ANSI SQL: 2015?