Database
 sql >> Datenbank >  >> RDS >> Database

SQL BETWEEN-Intelligente Tipps zum Scannen nach einem Wertebereich

SQL BETWEEN ist ein Operator, der verwendet wird, um einen Bereich von zu testenden Werten anzugeben. Der zurückgegebene Wert kann inklusive oder innerhalb des Bereichs sein. Oder es kann außerhalb des Bereichs liegen, wenn Sie den NOT-Operator davor einfügen. Es funktioniert für Datumsangaben, Datumsangaben mit Uhrzeit, Zahlen und Zeichenfolgen.

Sie können es in WHERE-Klauseln für Folgendes verwenden:

  • AUSWÄHLEN,
  • INSERT (mit SELECT)
  • AKTUALISIEREN,
  • und LÖSCHEN.

Es funktioniert auch für HAVING-Klauseln zusammen mit GROUP BY.

Aber wenn Sie nicht aufpassen, kann SQL BETWEEN Sie bei der Verwendung verrückt machen, insbesondere bei Datumsangaben mit Uhrzeit.

Aber keine Sorge. Wir haben Beispiele für die Fallstricke bei der Verwendung von SQL BETWEEN. Aber davor kamen die von mir verwendeten Beispieldaten von NOAA . Dort können Sie kostenlos Wetterdaten anfordern. Ich habe die stündlichen Temperaturaufzeichnungen für die Vereinigten Staaten im Jahr 2010 verwendet. Dann habe ich die CSV-Daten mit SQL Server Management Studio in den SQL Server importiert. Ich habe die Spalten umbenannt und einen nicht geclusterten Index hinzugefügt.

Fangen wir an.

SQL BETWEEN mit Datum und Uhrzeit verwenden

Dies muss das am häufigsten gesuchte Element sein, wenn es um SQL BETWEEN geht. Wir werden anhand von Beispielen erklären, wie es funktioniert.

Tipp Nr. 1:Geben Sie für DATETIME-Spalten sowohl das Datum als auch die Uhrzeit an

FALSCHE VERWENDUNG

Beginnen wir mit der falschen Verwendung, um diesen Punkt zu betonen. Die folgende Verwendung von BETWEEN mit DATETIME-Spalten führt zu unerwarteten Ergebnissen.


SELECT 
 DateHour
,Hourly_Heating_Degree_Hours
FROM TemperatureData
WHERE DateHour BETWEEN '01/01/2010' AND '01/02/2010'
AND Latitude = 41.995
AND Longitude = -87.9336;


Die Abfrage gibt Daten für 2 Tage von einer Wetterstation in der Nähe des O'Hare International Airport in Chicago zurück. Sie können den Bereich zwischen einem niedrigeren Wert (01.01.2010) und einem höheren Wert (01.02.2010) erkennen. Hier ist die Ergebnismenge in Abbildung 1.

Abbildung 1 . Ergebnismenge einer Abfrage mit SQL BETWEEN 2 data.

Aber wo ist das Problem?

Es soll eine stündliche Aufzeichnung für 2 Tage sein. Aus diesem Grund sollte die Ergebnismenge 48 Datensätze enthalten. Beachten Sie jedoch, dass es nur 24 sind. Das Problem liegt im Zeitelement von DateHour Säule. Wenn Sie die Uhrzeit nicht in einer DATETIME-Spalte angeben, wird 00:00 oder 0:00 Uhr angenommen. Beachten Sie außerdem, dass die Daten am 1. Januar 2010 um 01:00 Uhr und nicht um 00:00 Uhr begannen.

Intern hat SQL Server also DateHour verwendet ZWISCHEN 01.01.2010 00:00:00.000′ UND ’01.02.2010 00:00:00.000′ . Woher wissen wir das?

DAS DATUM IST EIGENTLICH EIN STRING

Das stimmt.

Die in einfachen Anführungszeichen eingeschlossenen Datumswerte sind eigentlich keine Datumsangaben, sondern Zeichenfolgen . SQL Server verwendet die implizite Konvertierung, um die Zeichenfolge in DATETIME zu konvertieren. Nach der Konvertierung wird der Zeitanteil an das Datum angehängt.

Lassen Sie uns mit Aktuellen Ausführungsplan einbeziehen prüfen . Drücken Sie Strg-M in SQL Server Management Studio, und führen Sie dann das vorherige Beispiel erneut aus.

Wenn der Ausführungsplan angezeigt wird, klicken Sie mit der rechten Maustaste auf Indexsuche -Operator und wählen Sie Eigenschaften aus . Siehe Abbildung 2.

Abbildung 2 . Implizite Konvertierung einer Zeichenkette in DATETIME. Es wird im Ausführungsplan einer Abfrage mit BETWEEN. versteckt

Erweitern Sie dann die Suchprädikate . Die eingerahmten Teile von Abbildung 2 zeigen die implizite Konvertierung der beiden Zeichenfolgen in DATETIME. Da implizite Konvertierung intern erfolgt , sind Neulinge verwirrt, warum ihre Erwartungen in der Ergebnismenge nicht erfüllt werden.

RICHTIGE VERWENDUNG

Das folgende Beispiel gibt die stündlichen Aufzeichnungen zwischen 8:00 und 12:00 Uhr am 2. Januar 2010 zurück.


SELECT * FROM TemperatureData
WHERE DateHour BETWEEN '01/02/2010 08:00' AND '01/02/2010 12:00'
AND Latitude = 41.995
AND Longitude = -87.9336;


Sie müssen den Zeitabschnitt angeben, insbesondere wenn die Daten gleich sind. Oder Ihre erwarteten Ergebnisse werden nicht eintreten.

Um die Aufzeichnungen für den ganzen Tag zurückzugeben, funktioniert dies nicht:


SELECT 
 DateHour
,Hourly_Heating_Degree_Hours
FROM TemperatureData
WHERE DateHour = '06/01/2010'
AND Latitude = 41.995
AND Longitude = -87.9336;


Es wird nur 1 Datensatz zurückgegeben – der für den 1. Juni 2010 um 00:00 Uhr. Wenn Sie jedoch BETWEEN mit den angegebenen Zeiten verwenden, können Sie den Datensatz jeder Stunde für den ganzen Tag zurückgeben. Siehe nächstes Beispiel.


SELECT 
 DateHour
,Hourly_Heating_Degree_Hours
FROM TemperatureData
WHERE DateHour BETWEEN '06/01/2010 00:00' AND '06/01/2010 23:00'
AND Latitude = 41.995
AND Longitude = -87.9336;


Beachten Sie, dass ich nur bis 23:00 angegeben habe. Wenn Ihre Daten eine beliebige Tageszeit verwenden, verwenden Sie 23:59 oder 23:59 Uhr im höheren Wert des Bereichs. Geben Sie die Sekunden auch an, wenn Sie das brauchen.

Tipp Nr. 2:Betrachten Sie den DATE-Datentyp

Wenn Sie den Zeitteil nicht benötigen, ziehen Sie stattdessen den Datentyp DATE in Betracht. Und Sie vermeiden die oben genannten Probleme.

SQL BETWEEN mit Zahlen

Kommen wir zu den Zahlen.

Tipp Nr. 3:Schließen Sie den Dezimalteil für nicht ganzzahlige Werte ein


SELECT
 DateHour
,[Hourly_Heating_Degree_Hours]
FROM TemperatureData
WHERE DateHour BETWEEN '06/01/2010' AND '06/5/2010 23:00'
AND [Hourly_Heating_Degree_Hours] BETWEEN 5.0 AND 7.0
AND Latitude = 41.995
AND Longitude = -87.9336;


Beachten Sie die Hinzufügung einer weiteren Bedingung, die Zahlen betrifft. Die Ergebnisse werden weiterhin auf 5 und 7 Grad begrenzt.

Wenn Sie die Datentypen DECIMAL, MONEY oder FLOAT verwenden, geben Sie den Dezimalteil auch dann an, wenn er Null ist, z. B. 52,00 oder 10,0000. So vermeiden Sie eine implizite Konvertierung zu den Zieldatentypen DECIMAL, MONEY oder FLOAT.

SQL BETWEEN mit Strings

Tipp Nr. 4:Bei Zeichenfolgen basiert der Bereich auf der Sortierung

Bei Zeichenfolgen wertet BETWEEN Werte basierend auf der alphabetischen Reihenfolge aus. „A“ ist die kleinste und „Z“ die größte. Man kann auch sagen, dass die Bewertung im Allgemeinen auf der Sortierung basiert. Weil Englisch nicht die einzige Sprache ist, die SQL Server unterstützt. Sammlung bietet Sortierregeln, Groß-/Kleinschreibung und Akzentsensitivität. Verwenden wir die AdventureWorks Datenbank für dieses Beispiel. Sehen Sie sich den Code unten und das Ergebnis in Abbildung 3 an.


USE AdventureWorks
GO

SELECT 
 LastName
,FirstName
,MiddleName
FROM Person.Person
WHERE Lastname BETWEEN 'Spanaway' AND 'Splane'
ORDER BY LastName;

Abbildung 3 . Ergebnismenge einer Abfrage mit BETWEEN mit Strings.

Der Bereich umfasst den Nachnamen Spanaway . Aber wo ist Splane ? Es ist in der Datenbank nicht vorhanden. Das Ergebnis reichte also nur bis Spicer .

SQL BETWEEN-Tipps für alle unterstützten Datentypen

Unabhängig davon, ob Sie BETWEEN für Datumsangaben, Zahlen oder Zeichenfolgen verwenden, gibt es allgemeine Dinge, die Sie beachten sollten. Das könnte gesunder Menschenverstand sein, aber es passiert immer noch aus Versehen. Lesen Sie weiter, wie das passieren kann.

Tipp Nr. 5:Start- und Endwert dürfen nicht NULL sein

BETWEEN benötigt Start- und Endwerte für den Bereich. Jeder sollte einen Wert haben, der nicht NULL ist. Unten finden Sie ein Beispiel mit einem NULL-Endwert.


SELECT 
 DateHour
,Hourly_Heating_Degree_Hours
FROM TemperatureData
WHERE DateHour BETWEEN '01/01/2010' AND NULL;


Dies kann passieren, wenn Sie die SELECT-Anweisung von einer App oder einer gespeicherten Prozedur aufrufen und sie nicht ordnungsgemäß validiert haben.

Tipp Nr. 6:Der Startwert darf nicht größer als der Endwert sein

Es wird auch nichts zurückgegeben, wenn beide Werte nicht NULL sind, aber der Bereich wird umgekehrt. Hier ist ein Beispiel.

SELECT 
 DateHour
,Hourly_Heating_Degree_Hours
FROM TemperatureData
WHERE DateHour BETWEEN '01/30/2010' AND '01/01/2010';


Abgesehen von Daten geben die folgenden Ausdrücke auch kein Ergebnis zurück:

  • Wert ZWISCHEN 100 UND -200. Weil -200 kleiner als 100 ist.
  • arbeiten ZWISCHEN „Zoowärter“ UND „Buchhalter“. Denn ‚Z‘ ist größer als ‚A‘.

Tipp Nr. 7:Bereichswerte sollten dieselben Datentypen haben

Manchmal haben Steuerelemente der Benutzeroberfläche eine unerwartete Ausgabe. Oder wir haben einfach das falsche Objekt ergattert. Und wenn wir es nicht überprüfen, bevor wir es an SQL Server weitergeben, kann eine Situation wie diese eintreten:


SELECT 
 DateHour
,Hourly_Heating_Degree_Hours
FROM TemperatureData
WHERE DateHour BETWEEN '06/01/2010' AND 'Saturday, June 5, 2010'
AND Latitude = 41.995
AND Longitude = -87.9336;

Es tritt ein Konvertierungsfehler von einer Zeichenfolge in ein Datum auf.

Die Lektion aus Tipp 5 bis 7 besteht also darin, die Anfangs- und Endwerte des Bereichs zu validieren .

Tipp Nr. 8:Verwenden Sie NOT BETWEEN, um Werte auszuschließen

Betrachten Sie ein weiteres Beispiel.


SELECT
 MONTH(DateHour) AS [Month] 
,round(AVG([Hourly_Heating_Degree_Hours]),2) AS AverageTemperature
FROM TemperatureData
WHERE DateHour BETWEEN '01/01/2010 00:00' AND '06/30/2010 23:00'
AND DateHour NOT BETWEEN '05/01/2010 00:00' AND '05/31/2010 23:00'
AND Latitude = 41.995
AND Longitude = -87.9336
GROUP BY MONTH(DateHour);


Dadurch wird der monatliche Durchschnitt von Januar bis Juni zurückgegeben, der Mai jedoch ausgeschlossen. Das Ausschließen der Aufzeichnungen für Mai 2010 wird durch NOT BETWEEN ermöglicht. Hier ist die Ergebnismenge in Abbildung 4.

Abbildung 4 . Ergebnismenge einer Abfrage mit NOT BETWEEN.

SQL BETWEEN im Vergleich zu anderen Operatoren

Tipp Nr. 9:Verwenden Sie IN, wenn Sie eine Liste und keinen Bereich benötigen

Der IN-Operator bestimmt, ob ein Wert mit einem beliebigen Wert in einer Liste oder Unterabfrage übereinstimmt. In der Zwischenzeit wird mit NOT IN geprüft, ob ein Wert nicht übereinstimmt.

Sowohl BETWEEN- als auch IN-Operatoren filtern Daten basierend auf mehreren Werten. Der Unterschied liegt jedoch in der Menge der abgeglichenen Werte. BETWEEN verwendet einen Bereich. Aber IN verwendet durch Kommas getrennte Werte in einer Liste oder Zeilen in einer Unterabfrage.

Sehen Sie sich das Beispiel unten an.

SELECT
 DateHour
,[Hourly_Heating_Degree_Hours]
FROM TemperatureData
WHERE DateHour BETWEEN '06/01/2010' AND '06/5/2010 23:00'
AND [Hourly_Heating_Degree_Hours] IN (5.2, 6, 7, 3.7)
AND Latitude = 41.995
AND Longitude = -87.9336;


Sehen Sie sich die Liste der von IN verwendeten Werte an. Es muss keine Liste mit steigenden Werten sein. Der letzte Wert in der Liste (3.7) ist auch der kleinste unter den Zahlen.

Tipp Nr. 10:Wählen Sie zwischen BETWEEN oder>=mit <=

Zur Laufzeit konvertiert SQL Server BETWEEN in>=mit <=-Operatoren. Woher wissen wir das?

Sehen Sie sich den Code unten an.


SELECT
 DateHour
,AVG(Hourly_Heating_Degree_Hours) AS AverageTemp
FROM TemperatureData
WHERE DateHour BETWEEN '01/01/2010 08:00' AND '01/01/2010 12:00'
GROUP BY DateHour;

SELECT
 DateHour
,AVG(Hourly_Heating_Degree_Hours) AS AverageTemp
FROM TemperatureData
WHERE DateHour >= '01/01/2010 08:00' 
AND DateHour <= '01/01/2010 12:00'
GROUP BY DateHour;


Beide Abfragen haben dieselbe Ergebnismenge wie die in Abbildung 5.

Abbildung 5 . Ergebnissatz mit entweder BETWEEN oder>=mit <=.

Sie haben auch den gleichen Ausführungsplan, wie in Abbildung 6 zu sehen.

Abbildung 6 . Ausführungsplan von 2 Abfragen, die die Verwendung der Operatoren BETWEEN und>=und <=vergleichen.

Aber hier ist die Sache.

Beachten Sie den ersten Index Suchen Operator in Abbildung 6. Sehen Sie sich dann die Suchprädikate an . Sehen Sie das Schlüsselwort BETWEEN? Es gibt keine, oder? Weil es mit <=Operatoren in>=umgewandelt wird. Das sind die Operatoren, die in den Suchprädikaten vorhanden sind .

Aber es gibt noch mehr.

Wenn Sie mit der Maus auf den zweiten Index Seek zeigen -Operator sehen Sie die gleichen Eigenschaften wie beim ersten Index Seek .

Es scheint also, dass der BETWEEN-Operator eine Abkürzung zu>=mit <=-Operatoren ist . Sie werden mehr eingeben, wenn Sie letzteres verwenden. Sie werden sehen, dass die gleiche Konvertierung stattfindet, wenn BETWEEN in Zahlen und Zeichenfolgen verwendet wird.

Am Ende liegt es an Ihnen, ob Sie BETWEEN oder die Operatoren>=und <=verwenden. Die Konvertierungszeit, die für die Konvertierung ZWISCHEN benötigt wird, ist vernachlässigbar. Aber wenn Sie diese zusätzliche, vernachlässigbare Zeit immer noch nicht wollen, verwenden Sie die Operatoren>=und <=.

Unterm Strich

SQL BETWEEN eignet sich gut zum Abrufen von Daten einschließlich des Bereichs. Und es ist nicht so schwer zu benutzen. Auch die DATETIME-Werte sind mit BETWEEN überschaubar. Stellen Sie nur sicher, dass Sie den Zeitabschnitt richtig abdecken. Es entspricht auch der Verwendung von>=mit <=. Es liegt an Ihnen, was Sie bevorzugen.

Sie können diese Seite mit einem Lesezeichen versehen, um bei Bedarf SQL BETWEEN-Tipps für Datumsangaben, Zahlen und Zeichenfolgen zu erhalten.

Wenn Sie einige Tricks mit BETWEEN haben, die wir nicht behandelt haben, können Sie sie uns im Kommentarbereich mitteilen. Und wenn Ihnen dieser Artikel gefällt, teilen Sie ihn bitte, indem Sie auf die Schaltflächen für soziale Medien klicken.

Allen viel Spaß beim Programmieren!