Halb offen (oder Halboffen, halb geschlossen , Halb Bounded ) Intervalle ( [a,b)
, wo x
dem 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 BETWEEN
ein geschlossenes Intervall verwendet ( [a,b]
)? Das ist esp. unpraktisch für Termine. Warum hättest du dich so BETWEEN
verhalten?
Antworten:
Ich denke, Inclusive
BETWEEN
ist 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.quelle
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:
Überlegen Sie, wie einfach es wird, auszudrücken
WHERE DATE_FIELD BETWEEN :dt INCLUSIVE AND :dt+1 EXCLUSIVE
(oder nurWHERE DATE_FIELD BETWEEN :dt AND :dt+1 EXCL
)Vielleicht ANSI SQL: 2015?
quelle
exp1 BETWEEN exp2 AND exp3 AND exp1 != exp3
wenn 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.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.quelle
a <= x < b
ist halboffen.Der Operator wird nicht aufgerufen
∩[a,b)
, er wird aufgerufenBETWEEN
, 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".quelle
BETWEEN
Bediener 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.