sql >> Databáze >  >> RDS >> PostgreSQL

Klauzule Care To Know:Vše o SELECT, FROM, WHERE, GROUP BY, HAVING, ORDER BY a LIMIT

SQL je jazyk databází a PostgreSQL je námi zvolený. Ukládání dat je často jen jedním aspektem procesu. Obvykle při jakémkoli úsilí zaměřeném na data budete:prohlížet a číst data, provádět akce nebo implementovat změny v datech, shromažďovat informace pro rozhodování (analytiku) nebo v nějaké formě či způsobem manipulovat s uloženými daty.

SQL se skládá z kombinace klíčových slov, příkazů a klauzulí. SQL vypadá jednoduše. Jen pár 'snadných “ velí sem a tam. Žádný velký problém, že?

V SQL je však více, než se na první pohled zdá. SQL vás může podrazit na těch 'snadných ' dotazy.

Jednou výzvou (kterou musím pravidelně opakovat) je pochopit, že pořadí provádění SQL se rozhodně liší od pořadí jeho syntaxe.

V tomto blogovém příspěvku na vysoké úrovni navštěvuji hlavní klauzule SQL, jak se vztahují na PostgreSQL. Existuje mnoho dialektů SQL, ale v centru pozornosti je výklad PostgreSQL. (Některé charakteristiky každé klauzule se velmi dobře mohou vztahovat na jiné dialekty SQL.)

Klauzule SQL tvoří základ pro základní, často používané příkazy a dotazy. Jak již bylo řečeno, pokročilé dotazy a příklady využívající funkce oken, CTE, odvozené tabulky atd. nebudou v tomto příspěvku zahrnuty.

Jak uvidíme, ne všechny věty jsou si rovny. Přesto fungují v tandemu a poskytují výsledky dotazů hladce (nebo ne).

Dovolte mi to objasnit...

Pravidelně se budu v blogovém příspěvku zmiňovat o exekučním příkazu, protože se vztahuje na mnoho klauzulí. Ale to je zobecněné.

Pokud tomu rozumím, optimalizátor častěji vybírá a rozhoduje o nejlepším plánu dotazů pro provedení.

SELECT – Klauzule „vybíravá“ používaná k dotazování na databázi

SELECT je jedna obsazená klauzule. je všude. Používá se více než všechny ostatní klauzule. Některé klauzule nemusíte vůbec potřebovat. Ne tak moc v případě SELECT, protože je to povinná klauzule.

Klauzule SELECT se obvykle používá pro dotazování na databázi, která obsahuje (na základní úrovni):

  1. Seznam SELECT – požadované sloupce dat.
  2. zdrojové datové sady – pojmenované v klauzuli FROM. Tabulky, pohledy, CTE atd. Odtud data pocházejí.
  3. volitelná klauzule WHERE používaná k filtrování řádků poskytovaných klauzulí FROM.

(Klauzule FROM a WHERE budou probrány v příslušných částech.)

Po pravdě bych řekl, že klauzule SELECT je v PostgreSQL vyžadována k načtení čehokoli. Ale pak je tu příkaz TABLE, který vrací všechny řádky a sloupce z tabulky.

Přesto je mezi nimi rozdíl. SELECT může specifikovat jednotlivé sloupce, ale pomocí příkazu TABLE jsou vráceny všechny sloupce.

VYBERTE zvýraznění:

  • SELECT * je zkrácený zápis a vrací všechny sloupce ze zdrojů dat.
  • Přestože je SELECT syntaxicky pojmenován jako první klauzule (s výjimkou dotazů používajících klauzuli WITH:zde není diskutováno), není proveden jako první. Je pozoruhodné, že ani SELECT není poslední klauzule, kterou lze provést.
  • Výrazu (nebo libovolnému sloupci) lze v klauzuli SELECT přiřadit referenční název nebo ALIAS s upozorněním. Tato křestní jména lze použít v klauzulích ORDER BY a GROUP BY, ale nikoli v klauzulích WHERE nebo HAVING.
  • Pokud je v dotazu přítomna klauzule GROUP BY (nebo agregační funkce), SELECT by neměl jmenovat žádné neseskupené sloupce. Pouze ty sloupce v jakýchkoli agregačních funkcích nebo ty, které jsou funkčně závislé na seskupených sloupcích.
  • Nejenže SELECT vrací konkrétní sloupce, ale jeho použití se rozšiřuje také na příkazy INSERT a CREATE TABLE.
  • Klauzule SELECT není zdaleka jednoduchá.

Podrobnější informace naleznete v sekci oficiální dokumentace klauzule PostgreSQL SELECT.

OD – Poskytuje zdroje dat pro dotaz

FROM je většinou povinná klauzule. Označuji to „volně ' kvůli dostupnému příkazu TABLE (zmíněnému výše), který nevyžaduje klauzuli FROM.

Pak znovu můžete vybrat libovolné výrazy bez pojmenované tabulky v dotazu SELECT. S TABLE to však není možné.

Zde je příklad v psql:

learning=> SELECT 2+2;
?column? 
----------
4
(1 row)

Ale s TABLE:

learning=> TABLE 2+2;
ERROR: syntax error at or near "2"
LINE 1: TABLE 2+2;
^

Některé dialekty SQL dokonce umožňují pojmenování neexistující tabulky, aby se zmírnilo neexistenci skutečné tabulky v klauzuli FROM. Přesto v PostgreSQL, jak můžete vidět z jednoduchého dotazu výše, to není vyžadováno.

Pokud však potřebujete vrácená skutečně uložená data kromě jednoduchých výrazů, budete potřebovat klauzuli FROM. Bez něj neexistují žádná data, se kterými by se dalo vůbec pracovat.

Proto je FROM bezpodmínečně nutné pro dotazování na jakékoli tabulky.

V Postgresu jsou všechny pojmenované tabulky v klauzuli FROM nejprve křížově spojeny (pokud není přítomna klauzule WITH) v příkazu provádění, který zakládá kartézský produkt. To dává smysl, protože potřebujeme data, se kterými můžeme pracovat.

Zde uvedená dokumentace FROM také poznamenává, že tato datová sada je obvykle redukována na malý počet řádků prostřednictvím současné podmínky klauzule WHERE.

Klauzule FROM přijímá řadu specifických prvků. Zde je jen několik (úplný seznam naleznete v dokumentaci níže):

  • Název tabulky (tento název samozřejmě potřebujeme).
  • POHLED.
  • Příkaz SELECT (poddotaz).
  • Název CTE (s klauzulí).
  • Typ JOIN – pokud existuje.
  • Funkce (toho jsem si nebyl vědom. Jak skvělé!!!)

Z hlavních bodů:

  • Přestože je FROM syntakticky uvedena jako druhá klauzule v dotazu SELECT, je provedena jako první.
  • FROM poskytuje (načtením) všechny řádky z libovolných tabulek (skutečných nebo virtuálních) uvedených ve své klauzuli.
  • Názvy tabulek mohou mít alias v klauzuli FROM (např. FROM bota AS), ale musí na ně tento ALIAS odkazovat během dalšího dotazu.
  • FROM je povinná klauzule při dotazování na tabulky.

Podrobné informace naleznete v části Oficiální klauzule PostgreSQL FROM.

KDE – Odfiltruje řádky ze zdrojů dat na základě booleovských podmíněných výrazů ověření

WHERE je volitelná klauzule. Je-li však v dotazu přítomen, jeho povinností je odstranit ty záznamy poskytované klauzulí FROM, které neprojdou booleovskou podmíněnou kontrolou.

Klauzule WHERE má kromě SELECT také hluboké použití s ​​dalšími příkazy SQL. Konkrétně příkazy DML jako INSERT (ne přímo, ale přes SELECT), UPDATE a DELETE.

Ve skutečnosti by bez klauzule WHERE příkazy UPDATE a DELETE pravděpodobně ovlivnily všechny cílové řádky. Možná ne to, co jste zamýšleli (Fuj!).

Agregační funkce nelze použít v booleovském podmíněném výrazu klauzule WHERE. K žádnému seskupení v exekučním řádu zatím nedošlo. Agregáty proto nejsou (zatím) pro klauzuli WHERE k dispozici.

Hodnocení WHERE je založeno na booleovské kontrole pomocí libovolného operátoru porovnání. (Např.>, <, =, <> atd...)

Klauzule WHERE nemá přístup k aliasovaným názvům sloupců uvedeným v klauzuli SELECT. Protože klauzule SELECT je ve skutečnosti (bez syntaxe) provedené po klauzuli WHERE, tyto aliasované sloupce ještě nejsou dostupné.

KDE zvýrazní:

  • Agregační funkce nejsou přístupné a nelze je použít v booleovské podmíněné kontrole klauzule WHERE. (Klauzule WHERE je možná zodpovědná za všechny řádky poskytnuté agregačním funkcím a seskupení pro výpočet.)
  • Na aliasované sloupce v klauzuli SELECT nelze odkazovat v klauzuli WHERE.
  • Podmíněná kontrola booleovského výrazu klauzule WHERE může mít za následek hodnotu true, false nebo NULL.
  • Všechny řádky, ve kterých je booleovský výraz klauzule WHERE vyhodnocen jako nepravda nebo NULL, jsou odstraněny.
  • Více booleovských podmínek lze zkontrolovat v klauzuli WHERE pomocí klíčových slov AND nebo OR.

Podrobné informace naleznete v části Oficiální klauzule PostgreSQL WHERE.

GROUP BY – Skupiny formulářů

Je volitelná klauzule.

Tato klauzule vytvoří jeden řádek pro vybrané, který obsahuje shodu se zadanou hodnotou seskupeného sloupce.

GROUP BY může být ošidné, proto považuji za vhodné zahrnout tuto pasáž z dokumentace:

"Pokud je přítomna GROUP BY nebo jsou přítomny jakékoli agregační funkce, není platné, aby se výrazy seznamu SELECT odkazovaly na neseskupené sloupce s výjimkou agregačních funkcí nebo když je neseskupený sloupec funkčně závislý na seskupených sloupcích, protože jinak by pro neseskupený sloupec lze vrátit více než jednu hodnotu. Funkční závislost existuje, pokud jsou seskupené sloupce (nebo jejich podmnožina) primárním klíčem tabulky obsahující neseskupený sloupec."

GROUP BY zvýraznění:

  • Postgres umožňuje seskupování nejen sloupců ze zdrojové tabulky, ale také sloupců uvedených v seznamu sloupců SELECT. To se mírně liší od striktního SQL.
  • V určitých dotazech může GROUP BY napodobovat klauzuli DISTINCT odstraněním duplicitních hodnot ze sloupce klauzule SELECT.
  • Pořadí sloupců je pro GROUP BY irelevantní.
  • Na sloupce, na které necílí klauzule GROUP BY, nelze odkazovat jinak než v souhrnech.
  • V mnoha případech můžete seskupit podle PRIMÁRNÍHO KLÍČE pro ty funkčně závislé sloupce tohoto klíče.
  • Seskupování se stále provádí pro dotazy využívající agregační funkce, pokud chybí klauzule GROUP BY.

Podrobné informace naleznete v části Oficiální klauzule PostgreSQL GROUP BY.

HAVING – Filtry GROUP BY Sloupce a agregační funkce

Je volitelná klauzule.

HAVING filtruje řádky ze sady výsledků pomocí booleovské podmíněné kontroly stejně jako klauzule WHERE, kromě toho, že filtruje řádky tvořené klauzulí GROUP BY a/nebo agregačními funkcemi.

MÁTE zvýraznění:

  • Klauzule HAVING může kromě sloupců GROUP BY odkazovat na sloupce uvedené v agregačních funkcích (i na ty, které nejsou seskupeny).
  • HAVING je zodpovědný za odstranění řádků po použití agregačních funkcí nebo seskupení.
  • Můžete odkazovat na neagregované sloupce v klauzuli HAVING, i když je to velmi málo užitečné.
  • Přestože se klauzule HAVING často používá ve spojení s klauzulí GROUP BY, můžete ji použít samostatně. Výsledky dotazů jsou tvořeny do jediné skupiny těchto sloupců pouze v agregačních funkcích.

Podrobné informace naleznete v části Oficiální klauzule PostgreSQL HAVING.

ORDER BY – Míra pořadí mimo náhodnost

Je volitelná klauzule.

Pokud potřebujete konkrétní objednávku, použijte ORDER BY. Jinak databáze může (a bude) vracet výsledky v libovolném pořadí.

I když se výsledky zdají být v určitém pořadí, není to zaručeno.

Nenechte se zmást. Použijte ORDER BY.

K dispozici jsou dva vzory objednání. Buď ASC (vzestupně) nebo DESC (sestupně) pořadí, přičemž ASC je výchozí.

Pokud má vaše sada výsledků obsahovat hodnoty NULL, lze je také použít v pořadí takto:zadáním hodnot NULLS LAST se budou (NULL) řadit po hodnotách, které nejsou NULL, zatímco požadavek NULLS FIRST je opačný.

ORDER BY highlights:

  • Výrazy řazení jsou všechny ty, které by byly povoleny v seznamu SELECT dotazu.
  • PostgreSQL umožňuje ORDER BY sloupce, které se nenacházejí v klauzuli SELECT, kde některé dialekty SQL ne.
  • Výsledky dotazů jsou vrtošivé a není zaručeno, že se budou podobat jakémukoli vzoru nebo objednávce, pokud není použita klauzule ORDER BY.
  • ORDER BY a klauzule LIMIT (viz další část) jsou skvělou kombinací pro určení 'Top ' sada výsledků řádků. (např. 5 dní s nejvyšším prodejem, 5 nejprodávanějších párů bot, nejlepší prodejce v tomto čtvrtletí)
  • Výsledky můžete seřadit podle pozičního čísla sloupce v seznamu SELECT, ale zadané číslo nesmí být větší než počet položek v uvedeném seznamu klauzulí SELECT. Jinými slovy, pokud má klauzule SELECT pouze 2 položky, pak ORDER BY 3 způsobí chybu.
  • Každý jednotlivý výraz je řazen pouze podle uvedené možnosti. (např. ORDER BY col_1 DESC, col_2 DESC není totéž jako ORDER BY col_1, col_2 DESC)

Podrobné informace naleznete v části Oficiální klauzule PostgreSQL ORDER BY.

Stáhněte si Whitepaper Today Správa a automatizace PostgreSQL s ClusterControlZjistěte, co potřebujete vědět k nasazení, monitorování, správě a škálování PostgreSQLStáhněte si Whitepaper

LIMIT – Načtení konkrétního počtu řádků z výsledků dotazu

LIMIT je volitelná klauzule.

LIMIT se ve skutečnosti skládá ze 2 pododstavců, přičemž OFFSET je druhou z nich.

Pokud je zadána hodnota pro část OFFSET klauzule, řádky sady výsledků se vrátí po přeskočení tohoto počtu řádků.

Důležitá část dokumentace, kterou je třeba poznamenat:

"Plánovač dotazů bere při generování plánu dotazů v úvahu LIMIT, takže je velmi pravděpodobné, že získáte různé plány (získáte různé pořadí řádků) v závislosti na tom, co používáte pro LIMIT a OFFSET. Použití různých hodnot LIMIT/OFFSET k výběru různých podmnožiny výsledku dotazu poskytnou nekonzistentní výsledky, pokud nevynutíte předvídatelné řazení výsledků pomocí ORDER BY. Nejedná se o chybu; je to inherentní důsledek skutečnosti, že SQL neslibuje dodání výsledků dotazu v žádném konkrétním pořadí. pokud není příkaz ORDER BY použit k omezení objednávky."

LIMIT zvýraznění:

  • LIMIT může vracet méně řádků, než je definovaný počet, pokud samotný dotaz produkuje méně řádků v sadě výsledků. Jinými slovy, nebude to mít žádný vliv na počet vrácených řádků.
  • Syntaxe LIMIT ALL je přijatelná a má stejný účinek, jako kdyby klauzuli LIMIT vůbec neobsahovala.
  • Přestože je počet řádků „x“ přeskočen kvůli klauzuli OFFSET, nejedná se o „řešení ' pro jakékoli zvýšení výkonu, protože jsou stále vypočítávány pro plán dotazů na serveru.
  • OFFSET 0 je ekvivalentní tomu, že klauzuli OFFSET vůbec nezahrnujete.

Podrobné informace naleznete v části Oficiální klauzule PostgreSQL LIMIT.

PostgreSQL interpretuje hlavní klauzule SQL jeho vlastní. Bez ohledu na to, jak se je PostgreSQL rozhodne implementovat nebo ne, jsou základem pro dotazy SQL a znalost jejich individuálních charakteristik (a nuancí) může uživatelům jedině prospět.

I když o každé z těchto klauzulí bylo napsáno množství článků, knih, dokumentace a blogových příspěvků, doufám, že tento přehled na vysoké úrovni shledáte stravitelným a informativním.

Děkuji za přečtení.


  1. Monitorování SQL databáze přes SP_WhoIsActive nebo FogLight | Řešení problémů s výkonem serveru SQL -1

  2. Použijte COLUMNPROPERTY() k vrácení informací o sloupcích nebo parametrech na serveru SQL Server

  3. SQL Server PIVOT možná?

  4. Chybová zpráva syntaxe MySQL Operand by měl obsahovat 1 sloupec(y)