Les intervalles semi-ouverts (ou semi-ouverts, semi-fermés , semi-délimités ) ( [a,b)
, où x
appartient à l'intervalle ssi a <= x < b
) sont assez courants en programmation, car ils possèdent de nombreuses propriétés pratiques.
Quelqu'un peut-il offrir une justification qui explique pourquoi SQL BETWEEN
utilise un intervalle fermé ( [a,b]
)? C'est esp. gênant pour les dates. Pourquoi voudriez-vous vous BETWEEN
comporter comme ça?
Réponses:
Je pense que l'inclusion
BETWEEN
est plus intuitive (et apparemment, les concepteurs SQL l'ont fait) qu'un intervalle semi-ouvert. Par exemple, si je dis "Choisissez un nombre entre 1 et 10", la plupart des gens incluront les nombres 1 et 10. L'intervalle ouvert est particulièrement déroutant pour les non-développeurs car il est asymétrique. SQL est parfois utilisé par des non-programmeurs pour faire des requêtes simples, et une sémantique semi-ouverte aurait été beaucoup plus déroutante pour eux.la source
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:
Considérez comme il est facile d’exprimer
WHERE DATE_FIELD BETWEEN :dt INCLUSIVE AND :dt+1 EXCLUSIVE
(ou tout simplementWHERE DATE_FIELD BETWEEN :dt AND :dt+1 EXCL
)Peut-être que ANSI SQL: 2015?
la source
exp1 BETWEEN exp2 AND exp3 AND exp1 != exp3
cette façon de garder l'opérateur entre les deux afin que vous sachiez que c'est un prédicat à distance, et le prédicat d'inégalité garantit qu'il est semi-ouvert.Les deux méthodes inclusive (
a <= x <= b
) et exclusive (a < x < b
) sont à peu près communes, il fallait donc en choisir une pour établir les normes. "Entre" en anglais commun est généralement inclusif, et une instruction SQL est conçue pour se lire de la même manière qu'une phrase anglaise. Inclus était donc un choix judicieux.la source
a <= x < b
est à moitié ouvert.L'opérateur n'est pas appelé
∩[a,b)
, il est appeléBETWEEN
, il est donc bien plus approprié que sa sémantique soit celle de la phrase anglaise "is between" que celle du prédicat mathématique "is in semi-open interval".la source
BETWEEN
opérateur n'utilise pas la sémantique de la phrase anglaise "is between". En anglais, "between" est le temps, l'espace ou l'intervalle qui sépare les choses (c'est-à-dire qu'il est exclusif ). Si vous essayez de marquer un but, le ballon doit passer entre les poteaux pour marquer. Si vous ne parvenez pas à passer le poteau entre les poteaux, aucun point pour vous.