Warum ist SQL ZWISCHEN inklusiv und nicht halboffen?


45

Halb offen (oder Halboffen, halb geschlossen , Halb Bounded ) Intervalle ( [a,b), wo xdem Intervall iff gehört a <= x < b) sind ziemlich häufig auf die Programmierung, da sie viele praktische Eigenschaften haben.

Kann jemand eine Begründung liefern, die erklärt, warum SQL BETWEENein geschlossenes Intervall verwendet ( [a,b])? Das ist esp. unpraktisch für Termine. Warum hättest du dich so BETWEENverhalten?


Ich bin gespannt, welche praktischen Eigenschaften sie haben.
Phant0m

2
Wenn es nicht inklusive wäre, wie könnten Sie dann leicht nach allen Nachnamen im Bereich von A bis D fragen? oder Namen W bis Z? Für Zahlen zwischen 1 und 10 können Sie nach 0 <n <11 suchen, aber für Zeichen müssten Sie ASCII-Zahlen verwenden? oder Unicode-Nummern? Mit den Indizes gelangen Sie außerdem problemlos zum Anfang Ihrer Daten.
JQA

2
Ich verstehe deine Frustration, (StartDate> = '2010-01-01' und StartDate <'2011-01-01'), funktioniert wunderbar, um zwischen dem Äquivalent (StartDate zwischen '2010-01-01' und ' 2010-12-31 23:59:59 '), sowohl sperrig als auch man muss wissen, wie viele Tage im Dezember sind
Todd

1
@ phant0m [a, b) U [c, d) == [a, d). [a: int, b: int) enthält genau ba-Elemente. Todd's Kommentar zeigt, wie sie besonders gut für Dates funktionieren (was ich am meisten vermisse). Grundsätzlich sind halboffene Intervalle beim Codieren in der Regel einfacher, benutzerfreundlicher und robuster.
alex

Die beste Antwort hätte auf die objektive Entscheidungsdokumentation der Personen verweisen müssen, die BETWEEN für SQL als Erstes angegeben haben, und dabei auf Why und nicht auf die ausgewählte subjektive Antwort geantwortet haben.
Todd

Antworten:


48

Ich denke, Inclusive BETWEENist intuitiver (und anscheinend auch die SQL-Designer) als ein halboffenes Intervall. Wenn ich zum Beispiel "Wähle eine Zahl zwischen 1 und 10" sage, werden die meisten Leute die Zahlen 1 und 10 einschließen. Das endlose Intervall ist für Nicht-Entwickler besonders verwirrend, da es asymmetrisch ist. SQL wird gelegentlich von Nicht-Programmierern verwendet, um einfache Abfragen zu erstellen, und semi-offene Semantik wäre für sie viel verwirrender gewesen.


9
Ihr Beispiel konzentriert sich auf Ganzzahlen. Bei Dezimalzahlen und anderen durch Trennzeichen getrennten Größen (z. B. Datumsangaben) ist der Begriff zwischen mehrdeutig. Wenn ich sage, haben Sie X zwischen 2012 und 2013 durchgeführt, schließe ich 2013 (oder speziell den Tag 2013-01-01)
Todd

4
@Todd Die Verwendung dieser Begriffe ist nicht eindeutig. Deshalb dokumentieren Mathematiker, Wissenschaftler und versierte Programmierer ihre Absicht als "halboffen" oder so. Ich denke, der Sinn von Oleskis Antwort ist, dass SQL ursprünglich eher für Endbenutzer als für Programmierer gedacht war (wirklich!). Anscheinend haben die SQL-Designer einen Versuch unternommen, eine Definition zu finden, die sie für dieses Publikum für am besten hielten. Wie die Verfasser der Frage jedoch vermuten lassen, eignet sich Half-Open fast immer besser für die Arbeit mit Bereichen wie Zeitspannen.
Basil Bourque

"Ich denke, inklusive ZWISCHEN ist intuitiver" ist subjektiv. "SQL wird gelegentlich von Nicht-Programmierern verwendet, um einfache Abfragen zu machen" - Nicht-Programmierer müssten ebenfalls die Spezifikation überprüfen.
Todd


Die Frage wird auch oft gestellt: "Wähle eine Zahl von 1 bis 10" (einfach, um die offensichtliche Mehrdeutigkeit zu vermeiden). Als Anmerkung. Sie sagen "wählen Sie eine Zahl zwischen 1 und 10"; Die meisten Leute würden wahrscheinlich nicht 1 oder 10 wählen. Zugegeben, das ist eher ein psychologisches Problem. :) Leute würden immer noch 1 und 10 als gültige Auswahl akzeptieren (obwohl sie semantisch inkorrekt sind); aber das ist ein Ergebnis der kontextuellen Interpretation unter der Annahme, dass 1 und 10 gültig sind. Wenn Sie sagen würden: "zwischen 13 und 24" und mit größerer Wahrscheinlichkeit gefragt werden, ob 13 und 24 enthalten sind.
Enttäuscht

26

FRAGE: Warum ist SQL ZWISCHEN inklusive?

ANTWORT: Da die SQL-Sprachentwickler eine schlechte Entwurfsentscheidung getroffen haben, konnten sie keine Syntax bereitstellen, mit der die Entwickler angeben konnten, welche der vier Varianten von BETWEEN (geschlossen, halboffen, halboffen, rechts oder offen) ) würden sie bevorzugen.

EMPFEHLUNG: Verwenden Sie ZWISCHEN nicht für Datums- / Uhrzeitangaben, es sei denn / bis der SQL-Standard geändert wird. Gewöhnen Sie sich stattdessen an, DATE-Bereichsvergleiche als unabhängige Bedingungen an den Start- und Endgrenzen Ihres BETWEEN-Bereichs zu codieren. Dies ist etwas ausführlich, lässt Sie jedoch Bedingungen schreiben, die für die Datenbankoptimierer intuitiv (und daher weniger fehleranfällig) und klar sind, sodass optimale Ausführungspläne ermittelt und Indizes verwendet werden können.

Wenn Ihre Abfrage beispielsweise eine Eingabe-Tagesangabe akzeptiert und alle Datensätze zurückgeben soll, die auf dieses Datum fallen, würden Sie Folgendes codieren:

  • WHERE DATE_FIELD >= :dt AND DATE_FIELD < :dt+1

Der Versuch, die Logik mit BETWEEN zu schreiben, birgt das Risiko von Leistungsproblemen und / oder fehlerhaftem Code. Drei häufige Fehltritte:

1) WHERE DATE_FIELD BETWEEN :dt AND :dt+1

Dies ist mit ziemlicher Sicherheit ein Fehler. Der Benutzer erwartet, dass nur Datensätze für ein bestimmtes Datum angezeigt werden. An einem Tag wird jedoch ein Bericht mit Datensätzen ab 12:00 Uhr des nächsten Tages angezeigt.

2) WHERE TRUNC(DATE_FIELD) = :dt

Gibt die richtige Antwort, aber das Anwenden der Funktion auf DATE_FIELD macht die meisten Indizierungen / Statistiken nutzlos (obwohl DBAs manchmal versuchen, durch Hinzufügen funktionsbasierter Indizes zu den Datumsfeldern zu helfen - sie verbrennen immer noch Arbeitsstunden und Speicherplatz und fügen Overhead zu IUD hinzu Operationen auf dem Tisch)

3) WHERE EVENT_DATE BETWEEN :dt AND :dt + 1-1/24/60/60

Tom Kyte, ein außergewöhnlicher Oracle-Guru, empfiehlt diese weniger elegante Lösung (IMO). Funktioniert hervorragend, bis Sie den ganzen Tag damit verbringen, das "1-1 / 24/06/60" in einer Abfrage zu finden, die unvollständige Ergebnisse liefert ... oder bis Sie es versehentlich in einem TIMESTAMP-Feld verwenden. Plus, es ist ein bisschen proprietär; Kompatibel mit dem DATE-Datentyp von Oracle (der auf die Sekunde genau verfolgt wird), muss jedoch an die DATE / TIME-Genauigkeit verschiedener Datenbankprodukte angepasst werden.

LÖSUNG: Bitten Sie das ANSI-SQL-Komitee, die SQL-Sprachspezifikationen zu verbessern, indem Sie die BETWEEN-Syntax ändern, um die Angabe von Alternativen zum CLOSED / INCLUSIVE-Standard zu unterstützen. So etwas würde den Trick machen:

expr1 ZWISCHEN expr2 [ INKL [USIVE] | EXCL [USIVE]] UND expr3 [ INCL [USIVE] | EXKLUSIV] ]

Überlegen Sie, wie einfach es wird, auszudrücken WHERE DATE_FIELD BETWEEN :dt INCLUSIVE AND :dt+1 EXCLUSIVE(oder nur WHERE DATE_FIELD BETWEEN :dt AND :dt+1 EXCL)

Vielleicht ANSI SQL: 2015?


Diese Antwort ist ein weiser Rat.
Basil Bourque

@ KevinKirkPatrick - Tolle Antwort! Ich schlage vor, Sie versuchen auch, die Entscheidungsdokumentation als objektiven Beweis für das ursprüngliche Warum zu finden.
Todd

3
Ich persönlich mag es, exp1 BETWEEN exp2 AND exp3 AND exp1 != exp3wenn Sie den Operator between beibehalten, damit Sie wissen, dass es sich um ein Bereichsprädikat handelt, und das Ungleichheitsprädikat gewährleistet, dass es halboffen ist.
Sentinel,

@Sentinel, schön! Ich werde mich nicht vorzeitig als Konverter deklarieren, aber ich werde diese Variante auf jeden Fall im Hinterkopf behalten, wenn ich das nächste Mal Bedingungen für den Datumsbereich codiere. Beim ersten Erröten hat es eine größere sprachliche Anziehungskraft als exp1> = exp2 AND exp1 <exp3; und löst offensichtlich Probleme mit ZWISCHEN ebenso gut. Es würde mich interessieren, ob Optimierer ein besseres "Verständnis" für eine Variation gegenüber der anderen zeigen. sicherlich scheint es plausibel, dass auch in dieser Hinsicht Ihre Ergebnisse besser sind (obwohl ich ehrlich gesagt ziemlich enttäuscht über den Optimierer sein würde, der sie unterschiedlich behandelt hat)
KevinKirkpatrick

@ KevinKirkpatrick Ich habe sie nie profiliert, um festzustellen, ob es Unterschiede gibt, und ich wäre auch enttäuscht, wenn es solche gäbe.
Sentinel,

8

Sowohl inclusive ( a <= x <= b) als auch exclusive ( a < x < b) sind ungefähr gleich häufig, sodass sie bei der Festlegung der Standards einfach einen auswählen mussten. "Between" in allgemeinem Englisch ist normalerweise inklusiv, und eine SQL-Anweisung sollte ähnlich wie ein englischer Satz lauten. Daher war inklusiv eine vernünftige Wahl.


4
Tatsächlich ist die Verwendung in Englisch noch uneinheitlicher, da Sie Half-Open ausgelassen haben. Wenn wir sagen , „Mittagessen ist zwischen Mittag und 13.00 Uhr“ meinen wir , halboffen, dass Sie in der Klasse / Arbeit im Moment von 13 erwartet zurück: 00: 00.000, mit der Pause gehe bis zu , aber nicht einschließlich dem ersten Augenblick die Ein-Uhr-Stunde. a <= x < bist halboffen.
Basil Bourque

1
@BasilBourque: Dies kann auf unendliche Präzision zurückzuführen sein - z. B. ist das Mittagessen zwischen Mittag und 12: 59: 99.99999999999 ....
Brendan

@Brendan Ja, Sie machen meinen Standpunkt. Die unendliche (oder mehrdeutige) Genauigkeit ist eines der Probleme, die durch die Verwendung des halboffenen Ansatzes zur Definition einer Zeitspanne gelöst werden. Der Punkt hier ist, dass wir in der englischen Konversation offen und geschlossen (wie in dieser Antwort erwähnt) sowie halboffene Bereiche intuitiv handhaben, ohne viel darüber nachzudenken. Jeder Ansatz dient einem Zweck. Deshalb ist die SQL-Definition von BETWEEN nicht optimal. Im Idealfall würde SQL dem Vorschlag von Kevin Kirkpatrick folgen .
Basil Bourque

2
SQL soll englischartig sein, und obwohl Inklusiv und Exklusiv gleichermaßen üblich sind, handelt es sich um eine Abfragesprache für Analysten und Programmierer. Als Programmierer denke ich, dass es falsch definiert ist, aber das spielt eigentlich keine Rolle, ich vermeide es einfach, "ZWISCHEN" zu verwenden. Keine große Sache.
Todd

5

Der Operator wird nicht aufgerufen ∩[a,b), er wird aufgerufen BETWEEN, daher ist es für seine Semantik wesentlich angemessener, die englische Phrase "is between" zu verwenden, als die des mathematischen Prädikats "is in semi-open interval".


Man muss alle Anwendungen berücksichtigen, nicht nur englische Anwendungen für Integer-Sets. "zwischen 1 und 10", "zwischen 12 und 13 Uhr", "zwischen 1,0 und 5,0" (Gramm). "zwischen 5,50 und 10,30" (Dollar). Kontinuierliche Mengen würden logischerweise (englisch) als exklusiv angenommen.
Todd

1
Das Problem ist , dass der BETWEENBediener nicht der Fall ist , die Semantik des englischen Begriff verwenden „zwischen“. Im Englischen ist "between" die Zeit, der Raum oder das Intervall , das die Dinge trennt (dh es ist exklusiv ). Wenn Sie versuchen, ein Tor zu schießen, muss der Ball zwischen den Pfosten liegen, um ein Tor zu erzielen. Wenn du den Pfosten triffst, der nicht zwischen ihnen überschreitet - keine Kerbe für dich.
Enttäuscht

1
@CraigYoung, wie die akzeptierte Antwort nahelegt (und ich stimme zu), "wenn ich" Wähle eine Zahl zwischen 1 und 10 "sage, werden die meisten Leute die Zahlen 1 und 10 [in ihrem Bereich möglicher Antworten] einschließen". In einem räumlichen Bereich stimme ich Ihnen zu, aber für Zahlen würde ich sagen, dass es anders ist. Besser für die englische Sprache und Verwendung als hier!
AakashM

@AakashM Mein Punkt ist, dass Sie eine Behauptung über die englische Sprache aufgestellt haben, die durch Wörterbuchdefinition des Wortes "zwischen" einfach falsch ist, um die Programmiersemantik zu rechtfertigen. Die Tatsache, dass es ein gemeinsames Verständnis der Phrase "zwischen 1 und 10" gibt, hat weniger mit der Bedeutung von "zwischen" zu tun als vielmehr mit den Positionen 1 und 10 im Dezimalzahlensystem. Die "automatische Korrektur" des menschlichen Gehirns ignoriert, dass "zwischen" in diesem Fall Endpunkte ausschließt, weil es lächerlich erscheint, "von 2 bis 9" zu bedeuten. Versuchen Sie dasselbe mit "zwischen 13 und 24". Oder auch "zwischen 0 und 11".
Desillusioniert

Zwischen Ihnen und mir sind kategorische Behauptungen über natürliche Sprachen normalerweise unsicher.
AakashM
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.