SQL är ett språk för databaser och PostgreSQL är vårt utvalda språk. Ofta är lagring av data bara en del av processen. Vanligtvis, i alla datacentrerade strävanden, kommer du att:se och läsa data, vidta åtgärder eller genomföra ändringar på data, samla in beslutsfattande information (analys) eller manipulera lagrad data på någon form eller sätt.
SQL består av en kombination av nyckelord, kommandon och satser. SQL verkar enkelt. Bara några enkla ' kommandon här och där. Ingen stor grej, eller hur?
Men det finns mer i SQL än vad man kan se. SQL kan göra dig uppmärksam på de 'enkla ' frågor.
En utmaning (som jag rutinmässigt måste se över) är att förstå att SQL-exekveringsordningen definitivt skiljer sig från dess syntax.
I det här blogginlägget besöker jag, på hög nivå, de stora SQL-klausulerna när de gäller PostgreSQL. Det finns många dialekter av SQL men PostgreSQL:s tolkning är i fokus här. (Vissa egenskaper hos varje sats kan mycket väl gälla andra SQL-dialekter.)
SQL-satser utgör grunden för grundläggande, ofta använda kommandon och frågor. Med det sagt, avancerade frågor och exempel som använder fönsterfunktioner, CTE:er, härledda tabeller etc kommer inte att täckas i det här inlägget.
Som vi kommer att se är inte alla klausuler skapade lika. Ändå fungerar de i tandem och ger sökresultat sömlöst (eller inte).
Tillåt mig att förtydliga...
Jag kommer med jämna mellanrum att nämna en exekutionsorder genom hela blogginlägget eftersom det gäller många av klausulerna. Men detta är generaliserat.
Såvitt jag förstår väljer och bestämmer optimeraren oftast den bästa frågeplanen för exekvering.
SELECT - Den "kräsna" klausulen som används för att söka i databasen
SELECT är en upptagen sats. Det finns överallt. Används mer än alla andra klausuler. Vissa klausuler kanske du inte behöver alls. Inte så mycket fallet med SELECT, för det är en obligatorisk klausul.
SELECT-satsen används vanligtvis för att fråga databasen, som innehåller (på en grundläggande nivå):
- En SELECT-lista – kolumnerna med data du vill ha.
- källdatauppsättningen/uppsättningarna - namngivna i FROM-satsen. Tabeller, vyer, CTE, etc. Det är därifrån data kommer.
- en valfri WHERE-sats som används för att filtrera rader som tillhandahålls av FROM-satsen.
(Från- och WHERE-satserna kommer att diskuteras i sina respektive avsnitt.)
I sanning skulle jag säga att SELECT-satsen krävs i PostgreSQL för att hämta någonting. Men sedan finns det kommandot TABLE som returnerar alla rader och kolumner från en tabell.
Ändå finns det en separation mellan de två. SELECT kan ange enskilda kolumner, men med kommandot TABLE returneras alla kolumner.
VÄLJ höjdpunkter:
- SELECT * är förkortad notation och returnerar alla kolumner från datakällorna.
- Även om SELECT syntaxmässigt heter den första satsen (med undantag för de frågor som använder en WITH-sats:diskuteras inte här), exekveras den inte först. Noterbart är att SELECT inte heller är den sista satsen som körs.
- Ett uttryck (eller valfri kolumn) kan ges ett referensnamn eller ALIAS i SELECT-satsen, med en varning. Dessa förnamn kan användas i ORDER BY och GROUP BY satser men inte WHERE eller HAVING satser.
- När en GROUP BY-sats förekommer (eller aggregerade funktioner) i frågan, ska SELECT inte namnge några ogrupperade kolumner. Endast de kolumner i någon aggregerad funktion(er) eller de som är funktionellt beroende av de grupperade kolumnerna.
- SELECT returnerar inte bara specifika kolumner, utan dess användning sträcker sig även till INSERT- och CREATE TABLE-satser.
- SELECT-satsen är långt ifrån enkel.
Se den officiella dokumentationen för PostgreSQL SELECT-klausulen för djupgående täckning.
FRÅN - Tillhandahåller datakällorna för frågan
FROM är för det mesta en obligatorisk klausul. Jag kallar detta "löst ' på grund av det tillgängliga TABLE-kommandot (som nämns ovan), som inte kräver FROM-satsen.
Återigen kan du välja godtyckliga uttryck, utan någon namngiven tabell i en SELECT-fråga. Men med TABLE är det inte möjligt.
Här är ett exempel i psql:
learning=> SELECT 2+2;
?column?
----------
4
(1 row)
Men med TABELL:
learning=> TABLE 2+2;
ERROR: syntax error at or near "2"
LINE 1: TABLE 2+2;
^
Vissa SQL-dialekter tillåter till och med namngivning av en icke-existerande tabell för att minska att inte ha en faktisk tabell i FROM-satsen. Ändå, i PostgreSQL, som du kan se från den enkla frågan ovan, är det inte nödvändigt.
Men om du behöver faktiskt lagrad data som returneras förutom enkla uttryck, kommer du att behöva FROM-satsen. Utan den finns det ingen data att ens operera på.
Därför är FROM absolut nödvändigt för att söka efter tabeller.
I Postgres korsfogas alla namngivna tabeller i FROM-satsen först (om en WITH-sats inte finns) i exekveringsordern som upprättar en kartesisk produkt. Detta är vettigt eftersom vi behöver data att arbeta med.
FROM-dokumentationen här noterar också att denna datamängd vanligtvis reduceras till ett litet antal rader via ett nuvarande WHERE-satsvillkor.
FROM-satsen accepterar ett antal specifika element. Här är bara några (se länkdokumentation nedan för hela listan):
- Tabellnamn (uppenbarligen behöver vi detta).
- EN VY.
- En SELECT-sats (en underfråga).
- CTE-namn (WITH-sats).
- Typ av JOIN - om någon.
- En funktion (jag var inte medveten om detta. Vad coolt!!!)
FRÅN höjdpunkter:
- Även om FROM syntaktiskt listas som den andra satsen i en SELECT-fråga, exekveras den först.
- FROM tillhandahåller (genom att ladda) alla rader från alla tabeller (verkliga eller virtuella) som nämns i dess klausul.
- Tabellnamn kan ha alias i FROM-satsen (t.ex. FROM shoe AS s) men måste refereras av det aliaset under hela frågan framåt.
- FROM är en obligatorisk klausul när man söker efter tabeller.
Se den officiella PostgreSQL FROM-klausulen för djupgående täckning.
WHERE - Filtrerar bort rader från datakällan/datakällorna baserat på boolesk valideringsvillkorliga uttryck
WHERE är en valfri klausul. Men när den är närvarande i en fråga är dess skyldighet att ta bort de poster som tillhandahålls av FROM-klausulen som inte klarar dess booleska villkorskontroll.
WHERE-satsen har också stor användning med andra SQL-kommandon utöver SELECT. Nämligen DML-kommandon som INSERT (inte direkt, utan via SELECT), UPDATE och DELETE.
Utan en WHERE-sats skulle UPDATE- och DELETE-satser sannolikt påverka alla målrader. Kanske inte vad du tänkt dig (Oj!).
Aggregatfunktioner kan inte användas i det booleska villkorsuttrycket för WHERE-satsen. Någon gruppering har ännu inte skett i exekutionsordern. Därför är aggregat inte tillgängliga (ännu) för WHERE-satsen.
WHERE-utvärderingen baseras på en boolesk kontroll med någon av jämförelseoperatorerna. (T.ex.>, <, =, <> osv...)
WHERE-satsen kan inte komma åt aliasade kolumnnamn listade i SELECT-satsen. Eftersom SELECT-satsen faktiskt är (inte syntaxmässigt) exekveras efter WHERE-satsen, dessa aliasade kolumner är ännu inte tillgängliga.
WHERE höjdpunkter:
- Aggregerade funktioner är inte tillgängliga och kan inte användas i den booleska villkorskontrollen av en WHERE-sats. (WHERE-satsen är möjligen ansvarig för att eventuella rader tillhandahålls för att aggregera funktioner och gruppera för beräkning.)
- Aliaserade kolumner i SELECT-satsen kan inte refereras i WHERE-satsen.
- WHERE-satsen booleska uttrycksvillkorskontroll kan resultera i antingen:true, false eller NULL.
- Alla rader där WHERE-satsen booleska uttrycket evalueras till false eller NULL tas bort.
- Flera booleska villkor kan kontrolleras i WHERE-satsen genom att använda AND- eller OR-nyckelorden.
Se den officiella PostgreSQL WHERE-klausulen för djupgående täckning.
GROUP BY - Formulärgrupper
Är en valfri klausul.
Denna sats skapar en enda rad för de valda, som innehåller en matchning på det angivna grupperade kolumnvärdet.
GROUP BY kan vara knepigt, därför anser jag att det är relevant att inkludera denna passage från dokumentationen:
"När GROUP BY finns, eller några aggregerade funktioner finns, är det inte giltigt för SELECT-listuttrycken att referera till ogrupperade kolumner förutom inom aggregerade funktioner eller när den ogrupperade kolumnen är funktionellt beroende av de grupperade kolumnerna, eftersom det annars skulle finnas mer än ett möjligt värde att returnera för en ogrupperad kolumn. Ett funktionellt beroende existerar om de grupperade kolumnerna (eller en delmängd därav) är primärnyckeln i tabellen som innehåller den ogrupperade kolumnen."
GRUPPER EFTER höjdpunkter:
- Postgres tillåter gruppering av inte bara kolumner från källtabellen utan även de som listas i SELECT-kolumnlistan. Detta skiljer sig något från strikt SQL.
- I vissa frågor kan GROUP BY härma DISTINCT-satsen genom att ta bort dubbletter av värden för SELECT-satskolumnen.
- Kolumnordning är irrelevant för GROUP BY.
- De kolumner som inte är inriktade på GROUP BY-satsen kan inte refereras förutom i aggregat.
- I många fall kan du gruppera på en PRIMÄRNYCKEL för de funktionellt beroende kolumnerna i den nyckeln.
- Gruppering utförs fortfarande för frågor som använder aggregerade funktioner i avsaknad av en GROUP BY-sats.
Se den officiella PostgreSQL GROUP BY-klausulen för djupgående täckning.
HA - Filtrerar GRUPPER EFTER kolumn(er) och samlade funktioner
Är en valfri klausul.
HAVING filtrerar rader från resultatuppsättningen med en boolesk villkorskontroll precis som WHERE-satsen, förutom att den filtrerar de rader som bildas av GROUP BY-satsen och/eller aggregatfunktioner.
HA höjdpunkter:
- HAVING-satsen kan referera till de kolumner som är namngivna i aggregerade funktioner (även de som inte är grupperade) utöver alla GROUP BY-kolumner.
- HAVING är ansvarigt för att ta bort rader efter att aggregerade funktioner eller gruppering har tillämpats.
- Du kan referera till icke-aggregerade kolumner i HAVING-satsen, även om det har mycket liten användning.
- Även om HAVING-satsen används många gånger i kombination med GROUP BY-satsen, kan du använda den ensam. Frågeresultat bildas endast i en enda grupp av dessa kolumner i aggregerade funktioner.
Se den officiella PostgreSQL HAVING-klausulen för djupgående täckning.
ORDER BY - A Measure of Order Out of Randomness
Är en valfri klausul.
Använd ORDER BY när du behöver specifik beställning. Annars kan (och kommer) databasen att returnera resultat i valfri godtycklig ordning.
Även om resultaten verkar vara i en viss ordning är detta inte garanterat.
Låt dig inte luras. Använd BESTÄLL AV.
Det finns två tillgängliga beställningsmönster. Antingen ASC (stigande) eller DESC (fallande) ordning, med ASC som standard.
Om din resultatuppsättning ska inkludera NULL-värden, kan de också användas i ordningsföljden enligt följande:att specificera NULLS LAST gör att de (NULLs) sorteras efter icke-NULLs medan begäran NULLS FIRST är det omvända.
BESTÄLL EFTER höjdpunkter:
- Sorteringsuttryck är något av de som skulle vara tillåtna i SELECT-listan för frågan.
- PostgreSQL tillåter dig att ORDER BY kolumner som inte finns i SELECT-satsen där vissa SQL-dialekter inte gör det.
- Frågeresultat är nyckfulla och kan inte garanteras likna något mönster eller ordning såvida inte en ORDER BY-sats används.
- ORDER BY och LIMIT-satsen (se nästa avsnitt) är bra kombinerade för att bestämma en "Topp ' rader resultatuppsättning. (t.ex. 5 högsta readagar, 5 lägst sålda par skor, bästa säljare detta kvartal)
- Du kan beställa resultat efter kolumnpositionsnummer i SELECT-listan, men det angivna antalet får inte vara större än antalet poster i SELECT-satslistan. Med andra ord, om SELECT-satsen bara har 2 objekt, kommer ORDER BY 3 att ge ett fel.
- Varje individuellt uttryck ordnas endast efter dess listade alternativ. (t.ex. ORDER BY col_1 DESC, col_2 DESC är inte detsamma som ORDER BY col_1, col_2 DESC)
Se den officiella PostgreSQL ORDER BY-klausulen för djupgående täckning.
Ladda ner Whitepaper Today PostgreSQL Management &Automation med ClusterControlLäs om vad du behöver veta för att distribuera, övervaka, hantera och skala PostgreSQLDladda WhitepaperLIMIT - Hämta ett specifikt antal rader från frågeresultaten
LIMIT är en valfri klausul.
LIMIT består faktiskt av 2 underklausuler, där OFFSET är den andra av dem.
Om ett värde anges för OFFSET-delen av satsen, returneras resultatuppsättningsrader efter hoppa över det antalet rader.
Ett viktigt avsnitt i dokumentationen att notera:
"Frågeplaneraren tar hänsyn till LIMIT när du skapar en frågeplan, så det är mycket troligt att du får olika planer (som ger olika radordningar) beroende på vad du använder för LIMIT och OFFSET. Använd alltså olika LIMIT/OFFSET-värden för att välja olika delmängder av ett frågeresultat kommer att ge inkonsekventa resultat om du inte tvingar fram en förutsägbar resultatordning med ORDER BY. Detta är inte en bugg, det är en inneboende konsekvens av det faktum att SQL inte lovar att leverera resultaten av en fråga i någon speciell ordning såvida inte ORDER BY används för att begränsa beställningen."
LIMIT höjdpunkter:
- LIMIT kan möjligen returnera färre rader än det definierade antalet om frågan i sig producerar färre rader i resultatuppsättningen. Med andra ord skulle det inte ha någon inverkan på antalet returnerade rader.
- LIMIT ALL syntax är acceptabel och har samma effekt som att inte inkludera en LIMIT-sats alls.
- Även om "x" antal rader hoppas över på grund av en OFFSET-sats, är detta inte en "lösning ' för eventuell prestandavinst, eftersom de fortfarande beräknas för frågeplanen på servern.
- OFFSET 0 motsvarar att inte inkludera en OFFSET-sats alls.
Se den officiella PostgreSQL LIMIT-klausulen för djupgående täckning.
PostgreSQL:s tolkning av de stora SQL-klausulerna är sin egen. Oavsett hur PostgreSQL väljer att implementera dem eller inte, är de grundläggande för SQL-frågor och förtrogenhet med deras individuella egenskaper (och nyanser) kan bara gynna användare framåt.
Även om mängder av artiklar, böcker, dokumentation och blogginlägg har skrivits om var och en av dessa klausuler, hoppas jag att du finner denna översikt på hög nivå lättsmält och informativ.
Tack för att du läser.