MySQL Sottoquery con esempi

โšก Riepilogo intelligente

MySQL La sintassi delle subquery inserisce un'istruzione SELECT all'interno di un'altra, in modo che il risultato della query interna alimenti la query esterna. Questa spiegazione illustra le subquery scalari, di riga e di tabella, l'ordine di esecuzione, esempi pratici e il compromesso in termini di prestazioni rispetto alle operazioni JOIN.

  • ๐Ÿ” Definizione di base: Una sottoquery รจ un'istruzione SELECT annidata all'interno di un'altra query, e la query interna viene eseguita per prima per fornire i valori alla query esterna.
  • ๐Ÿงฎ Sottoquery scalare: Restituisce una singola riga e una singola colonna, quindi si abbina bene con operatori di confronto come uguale, maggiore di o minore di.
  • ๐Ÿ“‹ Sottoquery di righe e tabelle: Una sottoquery di riga restituisce una riga con diverse colonne, mentre una sottoquery di tabella restituisce molte righe e funziona con l'operatore IN.
  • ๐Ÿงฉ Profonditร  di nidificazione: Le sottoquery possono essere annidate su piรน livelli, consentendo di individuare valori come, ad esempio, il membro che paga di piรน in un'unica istruzione.
  • โœ๏ธ Oltre SELECT: Le istruzioni INSERT, UPDATE e DELETE accettano subquery, il che rende possibili modifiche in blocco senza tabelle temporanee.
  • โšก Regola di prestazione: Un'operazione JOIN รจ generalmente molto piรน veloce di una subquery equivalente, quindi รจ consigliabile riservare le subquery per le logiche che una JOIN non puรฒ esprimere.

MySQL Sottoquery

Che cos'รจ una subquery in SQL?

A sottoquery Una query SELECT รจ una query SELECT contenuta all'interno di un'altra query. La query SELECT interna viene solitamente utilizzata per determinare i risultati della query SELECT esterna, quindi il database valuta prima l'istruzione interna e poi ne trasmette l'output verso l'alto.

La query interna รจ chiamata query interna o query nidificata, e l'istruzione che la contiene รจ chiamata interrogazione esternaAnalizziamo la sintassi della sottoquery.

MySQL Sottoquery

Il diagramma sopra mostra la struttura generale dell'istruzione: la clausola SELECT esterna specifica le colonne che si desidera visualizzare, mentre la clausola SELECT interna tra parentesi quadre specifica il valore o l'elenco di valori con cui la clausola WHERE effettua il confronto.

Perchรฉ utilizzare una sottoquery?

Prima di esaminare i diversi tipi, รจ utile sapere quando una subquery si merita di essere inserita in un'istruzione.

Una subquery risponde a una domanda il cui valore di filtro non รจ noto in anticipo. Deve essere calcolato a partire dai dati stessi. Un reclamo comune dei clienti della videoteca MyFlix riguarda il numero ridotto di titoli, e la direzione desidera acquistare film per la categoria con il minor numero di titoli. Nessuno sa quale sia questa categoria finchรฉ non viene interrogata il database, quindi il valore deve essere calcolato prima e poi utilizzato come filtro.

Le sottoquery sono atractive per tre ragioni pratiche:

  • leggibilitร : Ciascuna parte della logica รจ racchiusa in un blocco separato tra parentesi quadre, in modo che l'affermazione risulti come una sequenza di piccole domande piuttosto che come un'unica espressione complessa.
  • Isolamento: Una query interna puรฒ essere eseguita autonomamente per confermare che restituisca il valore atteso, il che semplifica notevolmente le fasi di test e debug.
  • Flessibilitร : Lo stesso schema funziona nelle clausole WHERE, HAVING, SELECT e FROM, nonchรฉ all'interno delle istruzioni INSERT, UPDATE e DELETE.

Il compromesso riguarda la velocitร , che verrร  esaminata nel confronto JOIN piรน avanti in questo articolo.

Tipi di sottoquery in MySQL

MySQL Il sistema supporta tre tipi di subquery, e il tipo viene determinato dalla struttura del risultato restituito dalla query interna. Ciascun tipo รจ spiegato di seguito con un esempio pratico sul database myflixdb.

1) Sottoquery scalare

A sottoquery scalare Restituisce esattamente una riga e una colonna, ovvero un singolo valore. Poichรฉ il risultato รจ un singolo valore, puรฒ essere utilizzato ovunque sia consentito un valore letterale. Riprendendo il problema di MyFlix menzionato in precedenza, รจ possibile utilizzare una query come questa:

SELECT category_name FROM categories
WHERE category_id = (SELECT MIN(category_id) FROM movies);

Fornisce un risultato:

MySQL Sottoquery

Vediamo come funziona questa query.

MySQL Sottoquery

Come mostra il diagramma di esecuzione, MySQL prime corse SELECT MIN(category_id) FROM movies, riceve un valore e solo allora esegue la query esterna con quel valore. Poichรฉ viene restituito un singolo valore, gli operatori consentiti sono quelli standard di confronto: =, <> (o !=), >, >=, <e <=.

Suggerimento: Se una sottoquery รจ posizionata dopo = restituisce piรน di una riga, MySQL genera l'errore 1242, La sottoquery restituisce piรน di una riga. Passare l'operatore a IN, oppure stringere la clausola WHERE interna.

2) Sottoquery di riga

A sottoquery di riga Restituisce anche una singola riga, ma tale riga puรฒ contenere piรน di una colonna. La query esterna, pertanto, confronta una riga di valori con un costruttore di riga anzichรฉ con un singolo valore.

SELECT full_names, contact_number FROM members
WHERE (membership_number, gender) = (SELECT membership_number, gender FROM members WHERE full_names = 'Janet Jones');

Gli operatori consentiti sono gli stessi operatori di confronto elencati sopra, applicati all'intera riga contemporaneamente.

3) Sottoquery della tabella

A sottoquery della tabella restituisce piรน righe e spesso piรน colonne, quindi la query esterna deve utilizzare un operatore di insieme come IN, NOT IN, ANY, ALL, o EXISTS.

Supponiamo di voler ottenere i nomi e i numeri di telefono degli utenti che hanno noleggiato un film e non lo hanno ancora restituito, in modo da poterli contattare per un promemoria. รˆ possibile utilizzare una query come questa:

SELECT full_names, contact_number FROM members
WHERE membership_number IN (SELECT membership_number FROM movierentals WHERE return_date IS NULL);

MySQL Sottoquery

Vediamo come funziona questa query.

MySQL Sottoquery

In questo caso, la query interna restituisce piรน di un risultato, quindi l'elenco dei numeri di iscrizione viene passato al IN operatore e ogni membro corrispondente viene restituito.

Sottoquery annidate su piรน livelli di profonditร 

Finora avete visto due livelli. Una sottoquery puรฒ contenere anche un'altra sottoquery, il che produce un'istruzione annidata tripla.

Supponiamo che la direzione voglia premiare il membro che paga di piรน. Possiamo eseguire una query come questa:

SELECT full_names FROM members
WHERE membership_number = (SELECT membership_number FROM payments
    WHERE amount_paid = (SELECT MAX(amount_paid) FROM payments));

La query piรน interna individua il pagamento piรน elevato, la query intermedia converte tale importo in un numero di iscrizione e la query piรน esterna converte il numero di iscrizione in un nome. La query sopra riportata produce il seguente risultato:

MySQL Sottoquery

Come utilizzare le subquery con INSERT, UPDATE e DELETE

Le subquery non si limitano alle istruzioni SELECT. Lo stesso schema tra parentesi funziona anche all'interno delle istruzioni di modifica dei dati, consentendo di modificare un intero set di righe in un'unica operazione senza creare una tabella temporanea.

INSERT con una sottoquery. Una subquery puรฒ fornire le righe da inserire, copiando i dati da una tabella all'altra. L'elenco delle colonne della SELECT deve corrispondere all'elenco delle colonne dell'INSERT.

INSERT INTO vip_members (membership_number, full_names)
SELECT membership_number, full_names FROM members
WHERE membership_number IN (SELECT membership_number FROM payments WHERE amount_paid > 5000);

AGGIORNA con una sottoquery. Qui la query interna decide quali righe vengono elaborate. L'esempio seguente contrassegna tutti i membri il cui affitto รจ ancora in sospeso.

UPDATE members
SET reminder_sent = 1
WHERE membership_number IN (SELECT membership_number FROM movierentals WHERE return_date IS NULL);

ELIMINA con una sottoquery. Lo stesso principio si applica alla rimozione delle righe che soddisfano una condizione presente in una seconda tabella.

DELETE FROM members
WHERE membership_number NOT IN (SELECT membership_number FROM movierentals);

โš ๏ธ Attenzione: MySQL non consente a un'istruzione di modificare una tabella e selezionare dalla stessa tabella all'interno di una sottoquery nella clausola FROM. Se viene visualizzato l'errore 1093, racchiudere la query interna in una tabella derivata, ad esempio SELECT * FROM (SELECT ...) AS t, Cosicchรฉ MySQL materializza il risultato prima che la modifica venga applicata. รˆ anche saggio eseguire prima la SELECT interna da sola e confermare il conteggio delle righe prima di eseguire un AGGIORNAMENTO DELETE in produzione.

Sottoquery vs. join

Sia una subquery che una JOIN possono combinare informazioni provenienti da piรน tabelle, quindi la domanda spontanea รจ quale delle due sia la piรน adatta.

Rispetto alle join, le subquery sono semplici da usare e facili da leggere. Non sono complicate come Entra a far partee quindi vengono spesso utilizzati da Principianti SQL.

Tuttavia, le subquery presentano problemi di prestazioni. L'utilizzo di un join al posto di una subquery puรฒ talvolta offrire un incremento delle prestazioni fino a 500 volte superiore, perchรฉ l'ottimizzatore รจ in grado di risolvere un join in un singolo passaggio anzichรฉ valutare ripetutamente l'istruzione interna.

Punto di confronto Sottoquery ISCRIVITI
leggibilitร  Alto, poichรฉ ogni blocco risponde a una domanda In basso, poichรฉ tutte le tabelle compaiono in un'unica clausola
Cookie di prestazione Piรน lentamente, la query interna potrebbe essere eseguita per ogni riga esterna. Piรน veloce, spesso con un margine molto ampio.
colonne dei risultati Vengono restituite solo le colonne della tabella esterna. รˆ possibile restituire le colonne di ogni tabella unita.
Utilizzo tipico Filtrare in base a un valore che deve essere calcolato per primo Combinazione di righe correlate provenienti da due o piรน tabelle
Curva di apprendimento Delicato, adatto ai principianti Piรน ripido, richiede la conoscenza dei tipi di giunzione

Data la possibilitร  di scelta, si consiglia di utilizzare un JOIN su una sottoquery. Le subquery dovrebbero essere utilizzate solo come soluzione di ripiego quando non รจ possibile utilizzare un'operazione JOIN per ottenere il risultato sopra descritto.

Sottoquery e join

Le subquery sono anche facili da scomporre in singoli componenti logici, il che รจ molto utile quando analisi e il debug delle query.

DOMANDE FREQUENTI

Una subquery correlata fa riferimento a una colonna della query esterna, quindi viene valutata una volta per ogni riga della query esterna. Una subquery non correlata รจ indipendente e viene eseguita una sola volta. Le subquery correlate sono potenti ma risultano sensibilmente piรน lente su tabelle di grandi dimensioni.

Una sottoquery puรฒ essere inserita nella clausola WHERE, nella clausola HAVING, nell'elenco SELECT o nella clausola FROM, dove diventa una tabella derivata e richiede un alias. รˆ valida anche all'interno delle istruzioni INSERT, UPDATE e DELETE.

Spesso sรฌ. Gli assistenti IA integrati negli editor come MySQL banco di lavoro puรฒ proporre un equivalente ISCRIVITIConfronta sempre il numero di righe e leggi il piano EXPLAIN prima di fidarti della riscrittura, perchรฉ la gestione dei valori NULL puรฒ variare.

Sรฌ. Gli assistenti Text to SQL trasformano una domanda come "quale categoria ha il minor numero di film" in una query SELECT nidificata. L'accuratezza dipende dallo schema fornito al modello, quindi รจ necessario confrontare l'istruzione generata con i nomi reali delle tabelle.

L'errore si verifica quando una sottoquery inserita dopo un operatore di confronto restituisce piรน righe. Sostituire l'operatore con IN, ANY o EXISTS, oppure restringere la clausola WHERE interna in modo che venga restituita una sola riga.

Riassumi questo post con: