Query nidificate in SQL
Il linguaggio SQL consente di nidificare una query all'interno di un'altra query. Ciò rende possibile scrivere una query molto grande che farà qualcosa di grande e complesso, sebbene la leggibilità del codice sia notevolmente ridotta.
A seconda di quanti valori vengono restituiti dalle sottoquery, l'area in cui possono essere applicati cambia. Ci sono tre opzioni in totale:
- La subquery restituisce un singolo valore (una colonna e una riga).
- La subquery restituisce un elenco di valori (una tabella con una colonna).
- La subquery restituisce una tabella (molte colonne, qualsiasi numero di righe).
Diamo un'occhiata a un esempio per ciascun caso.
Sottoquery con risultato scalare
Troviamo un elenco di tutti i nostri dipendenti dalla tabella dei dipendenti il cui stipendio è superiore alla media dell'azienda. Come possiamo farlo?
Possiamo facilmente filtrare i dipendenti confrontando il loro stipendio con la media se lo conosciamo in anticipo. Allo stesso tempo, abbiamo già scritto una query che ci consente di calcolare lo stipendio medio dei dipendenti dell'azienda. Ricordiamolo:
SELECT AVG(salary) FROM employee
Quindi MySQL ci ha restituito il valore: 76833.3333 .
Come trovare ora un elenco di tutti i dipendenti il cui stipendio è superiore alla media? È anche molto semplice:
SELECT * FROM employee
WHERE salary > 76833.3333
Il risultato di questa query sarà:
id | nome | occupazione | stipendio |
---|---|---|---|
1 | Ivanov Ivan | Programmatore | 100000 |
2 | Petrov Petr | Programmatore | 80000 |
4 | Rabinovich Moisha | Direttore | 200000 |
E ora combiniamo semplicemente entrambe le richieste sostituendo la prima richiesta invece del valore 76833:
SELECT * FROM employee
WHERE salary > (SELECT AVG(salary) FROM employee)
Il risultato di questa query sarà lo stesso:
id | nome | occupazione | stipendio |
---|---|---|---|
1 | Ivanov Ivan | Programmatore | 100000 |
2 | Petrov Petr | Programmatore | 80000 |
4 | Rabinovich Moisha | Direttore | 200000 |
Sottoquery con elenco di valori
Ricordi che una volta avevamo un compito: trovare tutti i record di una tabella per i quali non ci sono record corrispondenti di un'altra?
C'era anche questa foto:
![](https://cdn.codegym.cc/images/article/a0eff64c-0bb4-4480-833e-c1305cd03a5e/512.jpeg)
Se non sbaglio, l'attività è la seguente: visualizzare un elenco di tutti i dipendenti dalla tabella dei dipendenti per i quali non sono presenti attività nella tabella delle attività .
Troviamo anche una soluzione in due passaggi.
Innanzitutto, scriviamo una query che restituirà l'id di tutti i dipendenti che hanno attività nella tabella delle attività. Ricorda solo due cose:
- rimuovere i duplicati: utilizzare la parola chiave DISTINCT.
- rimuovere i valori NULL dal risultato.
SELECT DISTINCT employee_id FROM task
WHERE employee_id IS NOT NULL
E qui abbiamo ottenuto un bellissimo risultato di tale richiesta:
ID Dipendente |
---|
1 |
2 |
5 |
4 |
6 |
Scriviamolo temporaneamente per comodità come sequenza: 1,2,5,4,6. Ora scriviamo una seconda query - alla tabella dei dipendenti, che restituirà un elenco di dipendenti il cui id non è contenuto nel primo elenco:
SELECT * FROM employee
WHERE id NOT IN (1,2,5,4,6)
E il risultato di questa query:
id | nome | occupazione | stipendio | età | data di iscrizione |
---|---|---|---|---|---|
3 | Sergej Ivanov | Tester | 40000 | trenta | 2014-01-01 |
E ora, come nell'esempio precedente, puoi combinare entrambe le richieste semplicemente sostituendo il corpo della prima richiesta al posto dell'id list.
SELECT * FROM employee
WHERE id NOT IN (
SELECT DISTINCT employee_id FROM task
WHERE employee_id IS NOT NULL
)