Una sottoquery è un modo efficace per trovare i dati che si desidera utilizzare per un'altra query. Sono spesso utilizzati nelle istruzioni SELECT e UPDATE per rendere queste query più efficienti e facili da gestire.
Esistono diversi modi per utilizzare le sottoquery nelle istruzioni UPDATE. Diamo un'occhiata a ciascuno di essi.
IMPOSTA e sottoquery
Il primo metodo che esamineremo è l'utilizzo di una sottoquery nella clausola SET di un'istruzione UPDATE.
Diciamo che avevamo una tabella di prodotti simile a questa:
[id tabella=29 /]
Memorizza alcune informazioni sui diversi prodotti venduti da un'azienda.
Si supponga che l'azienda abbia deciso di aumentare il prezzo del prodotto "Couch" (ID prodotto 1). Tuttavia, invece di fissare un prezzo specifico, vogliono aumentarlo del 20% rispetto al prodotto più costoso che hanno.
Per fare ciò, possiamo utilizzare una sottoquery nella clausola SET. Potremmo utilizzare istruzioni separate, ma è più facile mantenerle utilizzando un'unica istruzione.
La nostra dichiarazione sarebbe simile a questa:
UPDATE product SET price = ( SELECT MAX(price) * 1.2 FROM product ) WHERE product_id = 1;
Puoi vedere che la clausola SET include una sottoquery, che trova il valore MAX della colonna del prezzo nella tabella del prodotto e lo moltiplica per 1,2 per aggiungere il 20%. Infine, la clausola WHERE è al di fuori della sottoquery per aggiornare solo il product_id di 1, poiché si applica a UPDATE anziché alla sottoquery.
Ciò comporterà la seguente modifica:
[id tabella=30 /]
SET e sottoquery correlata
Un altro modo per utilizzare una sottoquery in un'istruzione UPDATE consiste nell'utilizzare una sottoquery correlata.
Funziona in modo simile all'esempio precedente. Tuttavia, una sottoquery correlata è una sottoquery che fa riferimento all'istruzione esterna e può far parte di un'istruzione UPDATE.
Utilizzando i dati dell'esempio precedente (la tabella dei prodotti), l'azienda vuole disattivare tutti i prodotti per i quali non è stato effettuato un ordine. I dati per questo sono memorizzati nella tabella order_line.
Se l'abbiamo scritta come una sottoquery correlata, la query sarà simile a questa:
UPDATE product p SET active = ( SELECT CASE WHEN COUNT(*) > 0 THEN 'Y' ELSE 'N' END FROM order_line o WHERE o.product_id = p.product_id );
La sottoquery eseguirà una funzione COUNT utilizzando un'istruzione CASE per determinare se il valore restituito è Y o N a seconda del valore di COUNT. Viene calcolato per ogni product_id e corrisponde alla query esterna.
Ciò comporterà la colonna attiva per alcuni prodotti impostata su Y e altri impostata su N:
[id tabella=31 /]
DOVE Maggiore di Subquery
È possibile utilizzare una sottoquery anche nella clausola WHERE. Proprio come negli esempi precedenti, questo può essere fatto per rimuovere il passaggio separato di trovare un valore da aggiornare e quindi eseguire la query per aggiornarlo.
Possiamo continuare a lavorare con il nostro esempio dai passaggi precedenti. Supponiamo che l'azienda voglia attivare prodotti che hanno un prezzo superiore alla media. Per fare ciò, possiamo aggiungere una sottoquery alla clausola WHERE.
Innanzitutto, disattiva tutti i prodotti.
UPDATE product SET active = ’N’;
Quindi, aggiorna la tabella utilizzando la nostra sottoquery.
UPDATE product SET active = 'Y' WHERE price > ( SELECT AVG(price) FROM product );
Questo imposterà il valore attivo su Y per tutti i record che hanno un prezzo superiore alla media.
La tabella ora si presenta così:
[id tabella=32 /]
Mostra 2 record con un valore attivo di Y perché sono al di sopra della media.
Questo tipo di query può essere eseguito anche con altri operatori che consentono un singolo valore, come
WHERE IN Sottoquery
Inoltre, possiamo utilizzare una sottoquery con un operatore IN nella clausola WHERE.
È simile all'esempio precedente che utilizzava l'operatore maggiore di per un singolo valore. L'operatore IN può essere applicato a più valori.
Diciamo che l'azienda ha voluto aggiornare il prezzo di alcuni prodotti che erano l'unico articolo della categoria. I prezzi dovrebbero essere dimezzati.
La nostra query potrebbe essere simile a questa:
UPDATE product SET price = price / 2 WHERE category_id IN ( SELECT category_id FROM product GROUP BY category_id HAVING COUNT(*) = 1 );
La sottoquery trova tutti i valori category_id dove COUNT è 1. Non è necessario che COUNT sia nella parte SELECT della sottoquery, tuttavia, se lo facciamo, la query visualizzerà un errore.
L'istruzione UPDATE aggiornerà il prezzo in cui la categoria soddisfa i criteri della sottoquery.
I nostri risultati saranno quindi simili a questo:
[id tabella=33 /]
I dati sembrano molto simili. Tuttavia, il prezzo del prodotto con ID categoria 1 è stato aggiornato alla metà del suo costo originale, perché è l'unico prodotto nella sua categoria.
Aggiorna sottoquery
Infine, puoi utilizzare una sottoquery in un'istruzione UPDATE per aggiornare la tabella.
Negli esempi precedenti abbiamo semplicemente utilizzato la tabella dei prodotti. Tuttavia, puoi utilizzare una sottoquery invece della tabella dei prodotti, che restituirà un set di risultati che può essere aggiornato.
Il set di risultati deve essere aggiornabile, in modo simile al caso in cui si crea un oggetto VIEW e si tenta di aggiornarlo. Deve essere semplice e avere la chiave primaria.
Pertanto, utilizzando i nostri esempi precedenti, supponiamo che l'azienda voglia cambiare la categoria per tutti i prodotti che sono nella categoria 4 nella categoria 5.
La nostra query potrebbe essere simile a questa:
UPDATE ( SELECT product_id, category_id FROM product) SET category_id = 5 WHERE category_id = 4;
È un semplice esempio che dimostra il concetto. La tabella è stata sostituita con l'istruzione SELECT che mostra solo due colonne della tabella.
I risultati di questa query sarebbero:
[id tabella=34 /]
Lo stesso risultato potrebbe essere ricevuto spostando la clausola WHERE nell'istruzione UPDATE:
UPDATE ( SELECT product_id, category_id FROM product WHERE category_id = 4) SET category_id = 5;
Conclusione
L'uso di una sottoquery in un'istruzione UPDATE può essere un buon modo per migliorare la manutenibilità delle query. Può anche ridurre il numero di passaggi necessari per aggiornare i dati comprimendo due o più query in un'unica query.