PostgreSQL
 sql >> Database >  >> RDS >> PostgreSQL

Clausole di attenzione:tutto su SELECT, FROM, WHERE, GROUP BY, HAVING, ORDER BY e LIMIT

SQL è un linguaggio di database e PostgreSQL è il nostro prescelto. Spesso, la memorizzazione dei dati è solo un aspetto del processo. In genere, in qualsiasi attività incentrata sui dati, dovrai:visualizzare e leggere i dati, agire o implementare modifiche sui dati, raccogliere informazioni decisionali (analisi) o manipolare i dati archiviati in qualche forma o modo.

SQL è composto da una combinazione di parole chiave, comandi e clausole. SQL sembra semplice. Solo qualche 'facile ' comandi qua e là. Niente di grave, vero?

Ma c'è di più in SQL di quanto sembri. SQL può farti inciampare in quei 'facili ' interrogazioni.

Una sfida (che devo rivedere regolarmente) è capire che l'ordine di esecuzione di SQL è decisamente diverso da quello della sua sintassi.

In questo post del blog, visito, ad alto livello, le principali clausole SQL applicate a PostgreSQL. Esistono molti dialetti di SQL, ma l'interpretazione di PostgreSQL è al centro qui. (Alcune caratteristiche di ciascuna clausola possono essere applicate molto bene ad altri dialetti SQL.)

Le clausole SQL costituiscono la base per i comandi e le query di base utilizzati di frequente. Detto questo, le query avanzate e gli esempi che utilizzano le funzioni della finestra, i CTE, le tabelle derivate, ecc. non saranno trattati in questo post.

Come vedremo, non tutte le clausole sono uguali. Tuttavia, operano in tandem, fornendo risultati di query senza interruzioni (o meno).

Mi permetto di chiarire...

Menzionerò periodicamente di un ordine di esecuzione in tutto il post del blog poiché si applica a molte delle clausole. Ma questo è generalizzato.

Per quanto mi risulta, il più delle volte l'ottimizzatore sceglie e decide il miglior piano di query per l'esecuzione.

SELECT - La clausola "pignola" utilizzata per interrogare il database

SELECT è una clausola occupata. È ovunque. Usato più di tutte le altre clausole. Alcune clausole potrebbero non essere necessarie. Non tanto il caso di SELECT, perché è una clausola obbligatoria.

La clausola SELECT viene in genere utilizzata per interrogare il database, contenente (a livello di base):

  1. Un elenco SELECT - Le colonne di dati desiderate.
  2. il set di dati di origine - denominato nella clausola FROM. Tabelle, Viste, CTE, ecc. Ecco da dove provengono i dati.
  3. una clausola WHERE facoltativa utilizzata per filtrare le righe fornite dalla clausola FROM.

(Le clausole FROM e WHERE saranno discusse nelle rispettive sezioni.)

In verità, direi che la clausola SELECT è richiesta in PostgreSQL per recuperare qualsiasi cosa. Ma poi, c'è il comando TABLE che restituisce tutte le righe e le colonne da una tabella.

Eppure, c'è separazione tra i due. SELECT può specificare singole colonne, ma con il comando TABLE vengono restituite tutte le colonne.

SELEZIONA punti salienti:

  • SELECT * è una notazione abbreviata e restituisce tutte le colonne dalle origini dati.
  • Sebbene SELECT sia denominata dal punto di vista della sintassi come prima clausola (con l'eccezione di quelle query che utilizzano una clausola WITH:non discussa qui), non viene eseguita per prima. In particolare, SELECT non è nemmeno l'ultima clausola da eseguire.
  • A un'espressione (oa qualsiasi colonna) può essere assegnato un nome di riferimento o ALIAS nella clausola SELECT, con un avvertimento. I nomi dati possono essere utilizzati nelle clausole ORDER BY e GROUP BY ma non nelle clausole WHERE o HAVING.
  • Quando una clausola GROUP BY è presente (o funzioni aggregate) nella query, SELECT non deve nominare alcuna colonna non raggruppata. Solo quelle colonne in qualsiasi funzione aggregata o quelle funzionalmente dipendenti dalle colonne raggruppate.
  • Non solo SELECT restituisce colonne specifiche, ma il suo utilizzo si estende anche alle istruzioni INSERT e CREATE TABLE.
  • La clausola SELECT è tutt'altro che semplice.

Consulta la sezione della documentazione della clausola SELECT di PostgreSQL ufficiale per una copertura approfondita.

DA - Fornisce le origini dati per la query

FROM è principalmente una clausola obbligatoria. Lo chiamo 'vagamente ' a causa del comando TABLE disponibile (menzionato sopra), che non richiede la clausola FROM.

Inoltre, puoi selezionare espressioni arbitrarie, senza tabella denominata in una query SELECT. Tuttavia, con TABLE, ciò non è possibile.

Ecco un esempio in psql:

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

Ma con TABELLA:

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

Alcuni dialetti SQL consentono persino di nominare una tabella inesistente per ridurre la mancanza di una tabella effettiva nella clausola FROM. Tuttavia, in PostgreSQL, come puoi vedere dalla semplice query sopra, non è richiesto.

Ma, se hai bisogno di dati archiviati effettivi restituiti oltre alle semplici espressioni, avrai bisogno della clausola FROM. Senza di esso, non ci sono dati su cui operare.

Pertanto FROM è assolutamente necessario per interrogare qualsiasi tabella.

In Postgres, tutte le tabelle nominate nella clausola FROM vengono prima incrociate (se non è presente una clausola WITH) nell'ordine di esecuzione che stabilisce un Prodotto cartesiano. Questo ha senso perché abbiamo bisogno di dati con cui lavorare.

La documentazione FROM qui rileva inoltre che, in genere, questo set di dati viene ridotto a un numero ridotto di righe tramite una condizione della clausola WHERE presente.

La clausola FROM accetta una serie di elementi specifici. Eccone solo alcuni (per l'elenco completo, vedere la documentazione di collegamento di seguito):

  • Nome tabella (ovviamente ci serve questo).
  • UNA VISTA.
  • Un'istruzione SELECT (una sottoquery).
  • Nome CTE (CON clausola).
  • Tipo di JOIN - se presente.
  • Una funzione (non ne ero a conoscenza. Che figata!!!)

DA in evidenza:

  • Sebbene FROM sia elencata sintatticamente come seconda clausola in una query SELECT, viene eseguita per prima.
  • FROM fornisce (caricando) tutte le righe di qualsiasi tabella (reale o virtuale) indicata nella sua clausola.
  • I nomi delle tabelle possono essere alias nella clausola FROM (ad es. FROM shoe AS s) ma devono essere referenziati da quell'ALIAS per tutta la query che va avanti.
  • FROM è una clausola obbligatoria quando si interrogano le tabelle.

Consulta la sezione della clausola FROM di PostgreSQL ufficiale per una copertura approfondita.

WHERE - Filtra le righe dalle origini dati in base alle espressioni condizionali di convalida booleana

WHERE è una clausola facoltativa. Tuttavia, quando presente in una query, ha il compito di rimuovere quei record forniti dalla clausola FROM che non superano il controllo condizionale booleano.

La clausola WHERE ha anche un uso profondo con altri comandi SQL oltre a SELECT. Vale a dire, comandi DML come INSERT (non direttamente, ma tramite SELECT), UPDATE e DELETE.

In effetti, senza una clausola WHERE, le istruzioni UPDATE e DELETE influirebbero probabilmente su tutte le righe di destinazione. Forse non è quello che volevi (Yikes!).

Le funzioni aggregate non possono essere utilizzate nell'espressione condizionale booleana della clausola WHERE. Qualsiasi raggruppamento non è ancora avvenuto nell'ordine di esecuzione. Pertanto, gli aggregati non sono (ancora) disponibili per la clausola WHERE.

La valutazione WHERE si basa su un controllo booleano che utilizza uno qualsiasi degli operatori di confronto. (Es.,>, <, =, <>, ecc...)

La clausola WHERE non può accedere ai nomi di colonna con alias elencati nella clausola SELECT. Poiché la clausola SELECT è effettivamente (non per quanto riguarda la sintassi) eseguite dopo la clausola WHERE, quelle colonne con alias non sono ancora disponibili.

DOVE mette in evidenza:

  • Le funzioni aggregate non sono accessibili e non possono essere utilizzate nel controllo condizionale booleano di una clausola WHERE. (La clausola WHERE è possibilmente responsabile di eventuali righe fornite per aggregare funzioni e raggruppare per il calcolo.)
  • Le colonne con alias nella clausola SELECT non possono essere referenziate nella clausola WHERE.
  • Il controllo condizionale dell'espressione booleana della clausola WHERE può risultare in:true, false o NULL.
  • Tutte le righe in cui l'espressione booleana della clausola WHERE restituisce false o NULL vengono rimosse.
  • È possibile verificare più condizioni booleane nella clausola WHERE sfruttando le parole chiave AND o OR.

Consulta la sezione della clausola WHERE di PostgreSQL ufficiale per una copertura approfondita.

GRUPPO PER - Gruppi di moduli

È una clausola facoltativa.

Questa clausola crea una singola riga per quelle selezionate, che contiene una corrispondenza sul valore della colonna raggruppata specificato.

GROUP BY può essere complicato, quindi ritengo pertinente includere questo passaggio dalla documentazione:

"Quando è presente GROUP BY o sono presenti funzioni aggregate, non è valido che le espressioni dell'elenco SELECT facciano riferimento a colonne non raggruppate tranne che all'interno di funzioni aggregate o quando la colonna non raggruppata dipende funzionalmente dalle colonne raggruppate, poiché altrimenti più di un valore possibile da restituire per una colonna non raggruppata. Esiste una dipendenza funzionale se le colonne raggruppate (o un loro sottoinsieme) sono la chiave primaria della tabella contenente la colonna non raggruppata."

Raggruppa per punti salienti:

  • Postgres consente il raggruppamento non solo delle colonne della tabella di origine, ma anche di quelle elencate nell'elenco delle colonne SELECT. Questo è leggermente diverso da SQL rigoroso.
  • In alcune query, GROUP BY può imitare la clausola DISTINCT rimuovendo i valori duplicati per la colonna della clausola SELECT.
  • L'ordine delle colonne è irrilevante per GROUP BY.
  • Le colonne non targetizzate dalla clausola GROUP BY non possono essere referenziate se non in forma aggregata.
  • In molti casi, puoi raggruppare su una CHIAVE PRIMARIA le colonne funzionalmente dipendenti di quella chiave.
  • Il raggruppamento viene ancora eseguito per le query che utilizzano funzioni aggregate in assenza di una clausola GROUP BY.

Consulta la sezione della clausola GROUP BY ufficiale di PostgreSQL per una copertura approfondita.

HAVING - Filtri GROUP BY Colonna/e e funzioni di aggregazione

È una clausola facoltativa.

HAVING filtra le righe dai risultati impostati con un controllo condizionale booleano proprio come la clausola WHERE, tranne per il fatto che filtra le righe formate dalla clausola GROUP BY e/o dalle funzioni aggregate.

AVERE punti salienti:

  • La clausola HAVING può fare riferimento a quelle colonne denominate in funzioni aggregate (anche quelle non raggruppate) oltre a qualsiasi colonna GROUP BY.
  • HAVING è responsabile dell'eliminazione delle righe dopo l'applicazione di funzioni di aggregazione o raggruppamento.
  • Puoi fare riferimento a colonne non aggregate nella clausola HAVING anche se questa operazione ha un'utilità molto ridotta.
  • Sebbene la clausola HAVING sia usata molte volte insieme alla clausola GROUP BY, puoi usarla da sola. I risultati della query vengono formati in un unico gruppo di quelle colonne solo nelle funzioni aggregate.

Consulta la sezione della clausola HAVING ufficiale di PostgreSQL per una copertura approfondita.

ORDINE PER - Una misura dell'ordine per casualità

È una clausola facoltativa.

Usa ORDER BY quando hai bisogno di un ordine specifico. In caso contrario, il database può (e restituirà) risultati in qualsiasi ordinamento arbitrario.

Anche se i risultati sembrano essere in una parvenza di ordine, questo non è garantito.

Non farti ingannare. Usa ORDINA PER.

Sono disponibili due modelli di ordinazione. Ordine ASC (crescente) o DESC (decrescente), con ASC come predefinito.

Se il tuo set di risultati deve includere valori NULL, questi possono essere utilizzati anche nell'ordinamento come segue:specificando NULLS LAST fa in modo che (NULL) vengano ordinati dopo non NULL mentre richiedere NULLS FIRST è il contrario.

ORDINA PER highlights:

  • Le espressioni di ordinamento sono quelle che sarebbero consentite nell'elenco SELECT della query.
  • PostgreSQL ti consente di ordinare colonne non presenti nella clausola SELECT mentre alcuni dialetti SQL non lo fanno.
  • I risultati delle query sono capricciosi e non è garantito che assomiglino a modelli o ordini a meno che non venga utilizzata una clausola ORDER BY.
  • ORDER BY e la clausola LIMIT (vedi sezione successiva), sono ottimi combinati per determinare un 'Top ' righe risultati impostati. (ad es. 5 giorni di vendita più alti, 5 paia di scarpe più vendute, miglior venditore di questo trimestre)
  • Puoi ordinare i risultati in base al numero di posizione della colonna nell'elenco SELECT, ma il numero specificato non deve essere maggiore del numero di elementi in detto elenco di clausole SELECT. In altre parole, se la clausola SELECT ha solo 2 elementi, ORDER BY 3 produrrà un errore.
  • Ogni singola espressione è ordinata solo in base all'opzione elencata. (es. ORDER BY col_1 DESC, col_2 DESC non è uguale a ORDER BY col_1, col_2 DESC)

Consulta la sezione della clausola ORDER BY ufficiale di PostgreSQL per una copertura approfondita.

Scarica il whitepaper oggi Gestione e automazione di PostgreSQL con ClusterControlScopri cosa devi sapere per distribuire, monitorare, gestire e ridimensionare PostgreSQLScarica il whitepaper

LIMIT - Recupera un numero specifico di righe dai risultati della query

LIMIT è una clausola facoltativa.

LIMIT in realtà è costituito da 2 sotto-clausole, con OFFSET che è la seconda di esse.

Se viene fornito un valore per la parte OFFSET della clausola, le righe del set di risultati vengono restituite dopo saltando quel numero di righe.

Una sezione importante della documentazione da notare:

"Il pianificatore di query tiene conto di LIMIT durante la generazione di un piano di query, quindi è molto probabile che tu ottenga piani diversi (con ordini di riga diversi) a seconda di ciò che usi per LIMIT e OFFSET. Pertanto, utilizzando diversi valori LIMIT/OFFSET per selezionare diversi i sottoinsiemi del risultato di una query daranno risultati incoerenti a meno che non si applichi un ordinamento dei risultati prevedibile con ORDER BY. Questo non è un bug, è una conseguenza intrinseca del fatto che SQL non promette di fornire i risultati di una query in un ordine particolare a meno che ORDER BY non venga utilizzato per vincolare l'ordine."

LIMITE evidenzia:

  • LIMIT può eventualmente restituire meno righe del numero definito se la query stessa produce meno righe nel set di risultati. In altre parole, non avrebbe alcun impatto sul numero di righe restituite.
  • La sintassi LIMIT ALL è accettabile e ha lo stesso effetto di non includere affatto una clausola LIMIT.
  • Sebbene il numero 'x' di righe venga ignorato a causa di una clausola OFFSET, questa non è una 'soluzione alternativa ' per qualsiasi miglioramento delle prestazioni, poiché sono ancora calcolati per il piano di query nel server.
  • OFFSET 0 equivale a non includere affatto una clausola OFFSET.

Consulta la sezione sulla clausola LIMIT di PostgreSQL ufficiale per una copertura approfondita.

L'interpretazione di PostgreSQL delle principali clausole SQL è la sua. Indipendentemente dal modo in cui PostgreSQL scelga di implementarli o meno, sono fondamentali per le query SQL e la familiarità con le loro caratteristiche (e sfumature) individuali può solo avvantaggiare gli utenti in futuro.

Sebbene su ciascuna di queste clausole siano stati scritti volumi di articoli, libri, documentazione e post di blog, spero che troviate questa panoramica di alto livello digeribile e informativa.

Grazie per aver letto.