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?