sql >> Databáze >  >> RDS >> Database

SQL MEZI – chytré tipy pro vyhledávání řady hodnot

SQL BETWEEN je operátor používaný k určení rozsahu hodnot k testování. Vrácená hodnota může být včetně nebo v rozsahu. Nebo může být mimo rozsah, pokud před něj přidáte operátor NOT. Funguje to pro data, data s časem, čísla a řetězce.

Můžete jej použít na klauzule WHERE pro následující:

  • VYBRAT,
  • INSERT (pomocí SELECT)
  • AKTUALIZOVAT,
  • a DELETE.

Funguje také pro klauzule HAVING spolu s GROUP BY.

Ale pokud si nedáte pozor, SQL BETWEEN vás může při jeho používání zbláznit, zvláště u dat s časem.

Ale nebojte se. Máme příklady, jak se vypořádat s problémy při používání SQL BETWEEN. Předtím však vzorová data, která jsem použil, pocházela z NOAA . Můžete si od nich zdarma vyžádat údaje o počasí. Použil jsem hodinové teplotní záznamy pro Spojené státy v roce 2010. Poté jsem importoval data CSV na SQL Server pomocí SQL Server Management Studio. Přejmenoval jsem sloupce a přidal jsem neshlukovaný index.

Začněme.

Použití SQL BETWEEN s datem a časem

Toto musí být nejhledanější položka při práci s SQL BETWEEN. K vysvětlení, jak to funguje, použijeme příklady.

Tip #1:U sloupců DATETIME zadejte datum i čas

NESPRÁVNÉ POUŽITÍ

Začněme nesprávným použitím, abychom zdůraznili tento bod. Následující použití BETWEEN se sloupci DATETIME poskytne neočekávané výsledky.


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;


Dotaz vrací data za 2 dny z meteorologické stanice poblíž mezinárodního letiště O’Hare v Chicagu. Můžete si všimnout rozmezí mezi nižší hodnotou (01/01/2010) a vyšší hodnotou (01/02/2010). Zde je sada výsledků na obrázku 1.

Obrázek 1 . Výsledková sada dotazu používající data SQL BETWEEN 2.

Ale kde je problém?

Má to být hodinový rekord za 2 dny. Z toho důvodu by výsledná sada měla mít 48 záznamů. Ale všimněte si, že je to jen 24. Problém spočívá v časovém prvku DateHour sloupec. Když neurčíte čas ve sloupci DATETIME, předpokládá se 00:00 nebo 00:00. Upozorňujeme také, že data začala 1. ledna 2010 v 01:00, nikoli ve 00:00.

Interně tedy SQL Server používal DateHour MEZI ’01/01/2010 00:00:00.000′ A ’01/02/2010 00:00:00.000′ . Jak to víme?

DATUM JE VE SKUTEČNOSTI STRING

Je to tak.

Hodnoty data uzavřené v jednoduchých uvozovkách nejsou ve skutečnosti data, ale řetězce . SQL Server používá implicitní převod k převodu řetězce na DATETIME. Po převodu bude časová část připojena k datu.

Pojďme to zkontrolovat pomocí Zahrnout skutečný plán provedení . Stiskněte Ctrl-M v SQL Server Management Studio a poté znovu spusťte předchozí příklad.

Když se zobrazí prováděcí plán, klikněte pravým tlačítkem na Vyhledávání indexu operátora a vyberte Vlastnosti . Viz obrázek 2.

Obrázek 2 . Implicitní převod řetězce na DATETIME. Je skrytý v plánu provádění dotazu pomocí BETWEEN.

Poté rozbalte Hledat predikáty . Části obrázku 2 v rámečku ukazují implicitní převod 2 řetězců na DATETIME. Protože implicitní konverze se provádí interně , nováčci jsou zmateni, proč jejich očekávání v sadě výsledků nejsou splněna.

SPRÁVNÉ POUŽÍVÁNÍ

Níže uvedený příklad vrátí hodinové záznamy mezi 8:00 a 12:00 2. ledna 2010.


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;


Je třeba určit časovou část, zvláště když jsou data stejná. Nebo se vaše očekávané výsledky nedostaví.

Chcete-li vrátit záznamy za celý den, toto nebude fungovat:


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


Vrátí pouze 1 záznam – ten z 1. června 2010 ve 00:00. Ale pomocí BETWEEN se zadanými časy můžete vrátit záznam každé hodiny za celý den. Viz další příklad.


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;


Upozorňujeme, že jsem uvedl pouze do 23:00. Pokud vaše data používají jakoukoli denní dobu, použijte 23:59 nebo 23:59 ve vyšší hodnotě rozsahu. Pokud to potřebujete, zadejte také sekundy.

Tip #2:Zvažte typ dat DATE

Pokud nepotřebujete časovou část, zvažte místo toho datový typ DATE. A vyhnete se výše zmíněným potížím.

SQL BETWEEN s čísly

Pojďme k číslům.

Tip #3:Zahrňte desetinnou část pro necelé hodnoty


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;


Všimněte si přidání další podmínky zahrnující čísla. Výsledky budou dále omezeny na 5 a 7 stupňů.

Při použití datových typů DECIMAL, MONEY nebo FLOAT zadejte desetinnou část, i když je nula, například 52,00 nebo 10,0000. Vyhnete se tak implicitní konverzi na cílové datové typy DECIMAL, MONEY nebo FLOAT.

SQL BETWEEN s řetězci

Tip #4:U řetězců je rozsah založen na řazení

U řetězců BETWEEN vyhodnocuje hodnoty na základě abecedního pořadí. „A“ je nejmenší a „Z“ je největší. Můžete také říci, že obecně je hodnocení založeno na porovnávání. Protože angličtina není jediný jazyk, který SQL Server podporuje. Řazení poskytuje pravidla třídění, citlivost na malá a velká písmena a akcenty. Použijme AdventureWorks databáze pro tento příklad. Podívejte se na kód níže a výsledek na obrázku 3.


USE AdventureWorks
GO

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

Obrázek 3 . Výsledková sada dotazu pomocí BETWEEN s řetězci.

Rozsah pokrývá příjmení Spanaway . Ale kde je Splane ? V databázi neexistuje. Výsledek tedy dosáhl pouze Spicer .

SQL MEZI Tipy pro všechny podporované datové typy

Ať už pro data, čísla nebo řetězce používáte BETWEEN, měli byste si být vědomi běžných věcí. Může to být zdravý rozum, ale stále se to děje omylem. Přečtěte si, jak se to může stát.

Tip #5:Počáteční i koncová hodnota nesmí být NULL

BETWEEN potřebuje počáteční a koncové hodnoty rozsahu. Každý by měl mít hodnotu, která není NULL. Níže je uveden příklad s koncovou hodnotou NULL.


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


K tomu může dojít, pokud zavoláte příkaz SELECT z aplikace nebo uložené procedury a neověříte ji správně.

Tip #6:Počáteční hodnota nemůže být vyšší než koncová hodnota

Nic se také nevrátí, pokud obě hodnoty nejsou NULL, ale rozsah je obrácený. Zde je příklad.

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


Kromě dat nevrátí výsledek ani následující výrazy:

  • hodnota MEZI 100 AŽ -200. Protože -200 je nižší než 100.
  • práce MEZI ‚Zookeeperem‘ A ‚Účetním‘. Protože „Z“ je větší než „A“.

Tip #7:Hodnoty rozsahu by měly být stejné datové typy

Ovládací prvky uživatelského rozhraní mají někdy neočekávaný výstup. Nebo jsme si jen vybrali špatnou nemovitost. A pokud to nezkontrolujeme před tím, než to předáme SQL Server, může nastat podobná situace:


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;

Dojde k chybě převodu řetězce znaků na datum.

Poučení z tipů č. 5 až č. 7 je tedy ověření počáteční a koncové hodnoty rozsahu .

Tip #8:Použijte NOT BETWEEN k vyloučení hodnot

Zvažte jiný příklad.


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);


Tím se vrátí měsíční průměr od ledna do června, ale nezahrne květen. Vyloučení záznamů za květen 2010 umožňuje NE MEZI. Zde je sada výsledků na obrázku 4.

Obrázek 4 . Výsledková sada dotazu pomocí NOT BETWEEN.

SQL MEZI ve srovnání s jinými operátory

Tip #9:Použijte IN, pokud potřebujete seznam a ne rozsah

Operátor IN určuje, zda hodnota odpovídá jakékoli hodnotě v seznamu nebo poddotazu. Mezitím pomocí NOT IN zkontrolujete, zda se hodnota neshoduje.

Operátory BETWEEN i IN filtrují data na základě více hodnot. Rozdíl však spočívá v porovnané sadě hodnot. BETWEEN používá rozsah. Ale IN používá hodnoty oddělené čárkami v seznamu nebo řádcích v poddotazu.

Podívejte se na příklad níže.

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;


Podívejte se na seznam hodnot používaných IN. Nemusí to být seznam rostoucích hodnot. Poslední hodnota v seznamu (3.7) je také nejmenší mezi čísly.

Tip #10:Vyberte si mezi BETWEEN nebo>=pomocí <=

Za běhu SQL Server převádí BETWEEN na>=pomocí operátorů <=. Jak to víme?

Podívejte se na kód níže.


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;


Oba dotazy budou mít stejnou sadu výsledků jako dotaz na obrázku 5.

Obrázek 5 . Výsledek je nastaven pomocí BETWEEN nebo>=s <=.

Mají také stejný plán provádění, jak je vidět na obrázku 6.

Obrázek 6 . Plán provádění 2 dotazů porovnávajících použití operátorů BETWEEN a>=a <=.

Ale o to jde.

Všimněte si prvního Indexu Hledat operátor na obrázku 6. Poté se podívejte na Hledat predikáty . Vidíte klíčové slovo MEZI? Žádný není, že? Protože se převádí na>=pomocí operátorů <=. To jsou operátory přítomné v Hledat predikáty .

Ale je toho víc.

Pokud najedete myší na druhé Vyhledávání indexu operátora, uvidíte stejné vlastnosti jako u prvního Vyhledávání indexu .

Zdá se tedy, že operátor BETWEEN je zkratka pro>=s operátory <= . Pokud použijete to druhé, napíšete více. Ke stejnému převodu dojde, když se v číslech a řetězcích použije BETWEEN.

Nakonec je na vás, zda použijete operátory BETWEEN nebo>=a <=. Doba převodu potřebná k převodu BETWEEN je zanedbatelná. Pokud ale stále nechcete ten extra, zanedbatelný čas, použijte operátory>=a <=.

Sečteno a podtrženo

SQL BETWEEN je dobré pro načítání dat včetně rozsahu. A není to tak těžké používat. Dokonce i hodnoty DATETIME lze spravovat pomocí BETWEEN. Jen se ujistěte, že jste správně pokryli časovou část. Je to také ekvivalentní použití>=s <=. Je jen na vás, co preferujete.

Tuto stránku si můžete uložit do záložek a získat tipy SQL BETWEEN pro data, čísla a řetězce, když je budete potřebovat.

Pokud máte nějaké triky využívající BETWEEN, které jsme neprobrali, můžete se s námi o ně podělit v sekci Komentáře. A pokud se vám tento článek líbí, sdílejte jej stisknutím tlačítek sociálních sítí.

Šťastné kódování, všichni!


  1. Jak „odhalit“ číslo v MySQL

  2. Použití pivotu na více sloupcích řádku Oracle

  3. Jak vytvořit dočasnou funkci v PostgreSQL?

  4. Přečtěte si, jak vyladit výkon Microsoft SQL Server