Der SQL-Operator BETWEEN prüft, ob ein Wert innerhalb eines Bereichs liegt, und schließt dabei beide Grenzen ein. Genau diese scheinbare Einfachheit sorgt in echten Projekten für Fehler, vor allem bei Datum/Uhrzeit, Strings und Performance-Fragen rund um Index und Filterlogik.
Was macht SQL BETWEEN genau?
BETWEEN ist eine kompakte Schreibweise für zwei Grenzvergleiche mit >= und <=. Der Operator ist inklusiv, das heißt: Untere und obere Grenze gehören beide zum Ergebnis.
Viele Missverständnisse entstehen, weil Entwickler:innen intuitiv einen halb-offenen Bereich erwarten, wie er in manchen Programmiersprachen üblich ist. In SQL gilt jedoch bei WHERE preis BETWEEN 10 AND 20 dasselbe wie bei WHERE preis >= 10 AND preis <= 20. Das ist für Zahlen meist unproblematisch, bei Zeitstempeln aber schnell heikel.
Einfach lesbar ist Bereichsabfrage mit BETWEEN vor allem dann, wenn die Fachlogik einen geschlossenen Bereich meint. Typische Beispiele sind Preisintervalle, Punktzahlen, Altersgruppen oder fortlaufende IDs.
SELECT id, name, preis
FROM produkte
WHERE preis BETWEEN 10 AND 20
ORDER BY preis ASC;
Diese Abfrage liefert alle Produkte mit einem Preis von 10 bis 20 einschließlich beider Werte. Für numerische Spalten ist das gut lesbar und in der Regel eindeutig.
Unklar wird es erst dann, wenn Datentypen implizit konvertiert werden oder wenn der eigentliche Fachfall keinen geschlossenen Bereich, sondern ein Start-inklusive-Ende-exklusive-Verhalten verlangt. Gerade bei Berichten pro Tag oder Monat ist das häufiger der Fall als viele denken.
Wann ist BETWEEN sinnvoll – und wann eher nicht?
BETWEEN ist sinnvoll, wenn ein geschlossener Wertebereich fachlich korrekt ist und der Datentyp klar zur Grenze passt. Nicht ideal ist der Operator, wenn Grenzwerte dynamisch, zeitbasiert oder semantisch halb-offen gedacht sind.
Für Integer- oder Decimal-Werte ist BETWEEN oft eine gute Wahl. Bei Preisen, Lagerbeständen oder Bewertungsskalen verbessert der Operator die Lesbarkeit gegenüber zwei einzelnen Vergleichen. Auch bei Reports wirkt die Query dadurch oft kompakter.
Problematisch wird es bei DATETIME– oder TIMESTAMP-Spalten. Wer etwa alle Datensätze eines Tages abfragen will, schreibt häufig BETWEEN '2025-01-01' AND '2025-01-31'. Das kann je nach Datenbank und Spaltentyp dazu führen, dass Einträge am letzten Tag nach 00:00:00 nicht mehr enthalten sind.
Für solche Fälle ist ein halb-offener Bereich fast immer robuster: Start inklusive, Ende exklusiv. Dieses Muster passt besser zu Zeitintervallen, lässt sich sauber zusammensetzen und vermeidet Grenzprobleme bei Millisekunden oder unterschiedlichen Auflösungen.
SELECT id, erstellt_am
FROM bestellungen
WHERE erstellt_am >= '2025-01-01'
AND erstellt_am < '2025-02-01';
Diese Formulierung ist für Datums- und Zeitbereiche meist die bessere Wahl. Sie funktioniert stabiler, wenn erstellt_am Uhrzeiten enthält, und lässt sich für Tages-, Monats- oder Wochenfenster gut automatisieren.
- Nutze
BETWEENfür klar geschlossene Zahlenbereiche. - Verwende bei Zeitintervallen bevorzugt
>=und<. - Prüfe immer den echten Datentyp der Spalte, nicht nur das Anzeigeformat.
- Erwarte keine exklusive Obergrenze:
BETWEENschließt sie ein. - Teste Grenzwerte mit echten Beispieldaten statt nur mit leeren Tabellen.
Warum führt BETWEEN bei Datum und Uhrzeit so oft zu Fehlern?
Der häufigste Fehler mit BETWEEN betrifft Datum/Uhrzeit-Spalten, weil sichtbare Datumswerte und gespeicherte Zeitinformationen nicht dasselbe sind. Sobald eine Spalte Uhrzeiten enthält, reicht ein reines Datum als Obergrenze oft nicht aus.
Ein klassisches Beispiel: Eine Tabelle speichert Bestellungen in einer TIMESTAMP-Spalte. Die Query BETWEEN '2025-01-01' AND '2025-01-31' klingt nach gesamtem Januar, umfasst aber je nach SQL-Dialekt praktisch nur Werte bis 2025-01-31 00:00:00. Eine Bestellung am 2025-01-31 14:30:00 fällt dann heraus.
Genau deshalb ist das Muster mit exklusiver Obergrenze robuster. Es beschreibt den Bereich präziser und vermeidet Annahmen über Sekunden, Millisekunden oder interne Präzision. Wer regelmäßig Reports baut, spart damit spätere Fehlersuche.
Auch bei Archivabfragen oder Paginierung über Zeitfenster wird das Modell konsistenter. Zwei angrenzende Bereiche überschneiden sich nicht und lassen keine Lücken, wenn Ende und nächster Start sauber aneinander anschließen.
Bei komplexeren Reports hilft außerdem ein sauberer Aufbau mit CTE-Struktur oft, weil Zeitfenster, Vorfilter und Aggregationen leichter getrennt bleiben.
Was ist mit DATE-Spalten?
Bei einer reinen DATE-Spalte ohne Uhrzeit ist BETWEEN deutlich weniger riskant. Wenn nur Kalendertage gespeichert werden, umfasst BETWEEN '2025-01-01' AND '2025-01-31' tatsächlich den kompletten Zeitraum einschließlich des 31. Januar.
Trotzdem lohnt sich Konsistenz im Team. Wer mal mit DATE und mal mit DATETIME arbeitet, sollte bewusst zwischen beiden Fällen unterscheiden, statt dieselbe Schreibweise überall zu kopieren.
Was ist mit Zeitzonen?
Zeitzonen verschärfen das Problem zusätzlich. Wenn Anwendung, Datenbank und Reporting nicht dieselbe Zone verwenden, kann ein scheinbar korrekter Bereich fachlich trotzdem falsch sein.
Gerade in Backend-Systemen mit Node.js, Python 3.12 oder PHP 8.3 sollten Zeitpunkte möglichst eindeutig als UTC verarbeitet und erst in der Anzeige lokalisiert werden. Das reduziert Fehler, die sonst fälschlich als SQL-Problem erscheinen.
Wie verhält sich BETWEEN bei Strings und anderen Datentypen?
BETWEEN funktioniert nicht nur für Zahlen und Daten, sondern auch für Strings. Ob das fachlich sinnvoll ist, hängt aber stark von Sortierung, Kollation und erwarteter Semantik ab.
Bei Textspalten vergleicht die Datenbank Werte lexikografisch, also nach Sortierreihenfolge. Eine Abfrage wie WHERE name BETWEEN 'Anna' AND 'Marta' kann sinnvoll sein, wenn alphabetische Bereiche gewünscht sind. Sie ist aber weniger selbsterklärend als ein Präfixfilter mit LIKE oder ein gezielter Vergleich auf normalisierte Suchspalten.
Zusätzlich beeinflusst die Kollation, wie Groß-/Kleinschreibung und sprachspezifische Zeichen behandelt werden. Ein Bereich über Strings kann deshalb zwischen MySQL, PostgreSQL oder SQL Server unterschiedlich wirken, wenn Sortierregeln nicht explizit abgestimmt sind.
Bei numerischen Datentypen sollte außerdem klar sein, ob mit Ganzzahlen, Gleitkommazahlen oder exakten Dezimalwerten gearbeitet wird. Für Geldbeträge ist DECIMAL fast immer sinnvoller als FLOAT, weil Rundungsfehler sonst auch Bereichsfilter unzuverlässig machen können.
| Datentyp | BETWEEN oft sinnvoll? | Typischer Hinweis |
|---|---|---|
| INTEGER | Ja | Gut für IDs, Zähler, Scores |
| DECIMAL | Ja | Sauber für Preise und Grenzwerte |
| DATE | Meist ja | Grenzen sind klar auf Kalendertage bezogen |
| DATETIME / TIMESTAMP | Mit Vorsicht | Oft besser mit >= und < |
| VARCHAR / TEXT | Nur gezielt | Kollation und Sortierung prüfen |
Ist BETWEEN schlecht für die Performance?
BETWEEN ist nicht grundsätzlich langsam. Entscheidend für die Performance ist meist, ob die Abfrage sargable bleibt, also einen Index sinnvoll verwenden kann.
Auf einer indizierten Spalte kann BETWEEN sehr effizient sein, weil die Datenbank einen Bereich im Index durchsucht statt jede Zeile vollständig zu prüfen. Das gilt für PostgreSQL ebenso wie für MySQL oder MariaDB in typischen B-Tree-Szenarien.
Schlechter wird es, wenn Funktionen auf die Spalte angewendet werden. Eine Bedingung wie WHERE DATE(erstellt_am) BETWEEN '2025-01-01' AND '2025-01-31' sieht bequem aus, zerstört aber oft die gute Nutzbarkeit des Index. Besser ist es, den Bereich direkt auf der Originalspalte zu formulieren.
Wer Query-Pläne liest, erkennt schnell, ob ein Bereichsfilter sauber arbeitet. Gerade bei größeren Tabellen lohnt sich ein Blick auf EXPLAIN-Auswertung, weil dort sichtbar wird, ob ein Range Scan oder ein Full Table Scan stattfindet.
SELECT id, erstellt_am
FROM bestellungen
WHERE DATE(erstellt_am) = '2025-01-31';
Diese Variante ist oft schlechter als ein direkter Bereich auf erstellt_am. Nicht der Vergleich selbst ist das Problem, sondern die Funktion auf der linken Seite der Bedingung.
Auch zusammengesetzte Indizes spielen eine Rolle. Wenn ein Bereichsfilter auf der zweiten oder dritten Spalte eines Composite Index liegt, hängt die Nutzbarkeit stark von der Reihenfolge der Spalten und weiteren Gleichheitsfiltern ab. Für tiefergehende Performance-Arbeit ist außerdem saubere Indexwahl entscheidend.
Welche Alternativen zu BETWEEN sind oft klarer?
BETWEEN ist nicht immer die beste Formulierung. Explizite Vergleiche mit >=, <= oder < sind oft klarer, wenn die Fachlogik an Grenzverhalten hängt.
Für Zeiträume ist die Kombination >= start und < ende meist die robusteste Variante. Für ungleichmäßige Bereiche oder dynamisch berechnete Grenzen können einzelne Vergleiche ebenfalls verständlicher sein. In Reviews ist sofort sichtbar, ob die Obergrenze eingeschlossen ist oder nicht.
Wenn Bereiche auf Aggregationen oder abgeleiteten Daten beruhen, können bedingte Fallunterscheidungen mit CASE WHEN oder vorgelagerte CTEs die bessere Lesbarkeit bieten. Das gilt besonders dann, wenn Business-Regeln wie Tarifstufen, SLA-Fenster oder Bonusklassen im Spiel sind.
- Schreibe bei Zeitfenstern standardmäßig
>= startund< ende. - Vermeide Funktionen auf filternden Spalten, wenn ein Index genutzt werden soll.
- Nutze
BETWEENbevorzugt für numerische oder echteDATE-Bereiche. - Dokumentiere Grenzlogik im Team konsistent, besonders bei Reports.
- Teste Queries immer mit Werten direkt an der unteren und oberen Grenze.
Was ist der Unterschied zwischen BETWEEN und >= / <=?
Fachlich gibt es bei geschlossenen Bereichen keinen Unterschied. BETWEEN a AND b entspricht >= a AND <= b.
Der Unterschied liegt vor allem in Lesbarkeit und Absicht. Sobald die obere Grenze exklusiv sein soll, ist die explizite Schreibweise klarer.
Ist NOT BETWEEN sinnvoll?
NOT BETWEEN ist erlaubt und kann lesbar sein, wenn wirklich ein ausgeschlossener Bereich gemeint ist. In komplexen Bedingungen wird die Logik mit < oder > aber oft verständlicher, weil Negationen schneller Denkfehler erzeugen.
Funktioniert BETWEEN in allen SQL-Datenbanken gleich?
Das Grundprinzip ist in gängigen relationalen Datenbanken gleich: Die Grenzen sind inklusiv. Unterschiede entstehen eher durch Datentypen, Kollation, implizite Konvertierungen und Optimizer-Verhalten als durch den Operator selbst.
SQL BETWEEN ist dann stark, wenn der Bereich fachlich wirklich geschlossen ist und der Datentyp sauber dazu passt. Für Zahlen und echte Datumsspalten ist der Operator oft lesbar und unproblematisch, bei Zeitstempeln sollte die exklusive Obergrenze aber meist Standard sein. Performance-Probleme entstehen selten durch BETWEEN selbst, sondern durch Funktionen auf Spalten, ungeeignete Datentypen oder fehlende Indizes. Wer Grenzwerte bewusst modelliert, vermeidet stille Fehler in Reports, Filtern und produktiven Abfragen.

