CodeGym /Corsi /SQL SELF /Uso di SELECT dentro SELECT

Uso di SELECT dentro SELECT

SQL SELF
Livello 13 , Lezione 1
Disponibile

Immagina di lavorare come analyst in un'università (stiamo facendo un database per l'università, ti ricordi?). Ti hanno chiesto non solo di mostrare gli studenti e i loro voti, ma anche di aggiungere una colonna con il voto massimo nel gruppo, così puoi confrontare facilmente i risultati. Come risolvi questa cosa? Ovviamente, usando le subquery dentro SELECT!

Una subquery in SELECT ti permette di calcolare valori direttamente mentre la query principale gira. È una figata, perché puoi combinare calcoli aggregati, filtri complessi e anche altre collezioni di dati in una sola query.

Basi delle query annidate in SELECT

Una subquery in SELECT funziona proprio come sembra: inserisci il risultato di una SELECT dentro un'altra. Così puoi calcolare valori extra per ogni riga del risultato.

Ecco un esempio semplice. Supponiamo di avere una tabella students con questa struttura:

student_id name group_id
1 Linda 101
2 Otto 102
3 Anna 101

E la tabella grades:

grade_id student_id grade
1 1 5
2 1 4
3 2 3
4 3 5
5 3 4

Esempio 1: Aggiungere il voto massimo nel gruppo

Obiettivo: mostrare i nomi degli studenti, i loro voti e il voto massimo nel gruppo, così si vede subito quanto i voti di ogni studente sono diversi dai migliori risultati del gruppo.

Codice SQL:

SELECT
    s.name AS student_name,
    g.grade AS student_grade,
    (
        SELECT MAX(grade) -- questa query restituisce un solo valore 
        FROM grades 
        INNER JOIN students ON grades.student_id = students.student_id
        WHERE students.group_id = s.group_id
    ) AS max_group_grade 
FROM 
    students s
INNER JOIN 
    grades g ON s.student_id = g.student_id;

Cosa succede qui:

  1. Per ogni studente prendiamo il suo nome e il suo voto (s.name, g.grade).
  2. SELECT MAX(grade) — questa è la subquery che restituisce il voto massimo dentro il gruppo dello studente.
  3. La subquery viene eseguita per ogni riga della query principale e usa la condizione WHERE students.group_id = s.group_id per limitare la selezione a un solo gruppo.

Esempio 2: Voto medio per gruppo

Vuoi essere ancora più utile per gli analyst? Aggiungiamo all'output non solo il voto massimo, ma anche il voto medio del gruppo.

Codice SQL:

SELECT
    s.name AS student_name,
    g.grade AS student_grade,
    (
        SELECT AVG(grade) 
        FROM grades 
        INNER JOIN students ON grades.student_id = students.student_id
        WHERE students.group_id = s.group_id
    ) AS avg_group_grade
FROM 
    students s
INNER JOIN 
    grades g ON s.student_id = g.student_id;

Adesso:

  • Invece di MAX() usiamo AVG() per calcolare il voto medio nel gruppo.
  • Otteniamo un'analisi "live" dei dati.

Limitazioni e consigli

Le subquery in SELECT sono potenti, ma vanno usate con attenzione:

  1. Performance. Ogni subquery viene eseguita per ogni riga della query principale. Questo può rallentare la query SQL se le tabelle sono grandi. Tipo, se hai 1000 studenti, la subquery gira 1000 volte!
  2. Indici. Per velocizzare queste query, è importante indicizzare bene le colonne usate nelle condizioni WHERE della subquery.
  3. Leggibilità. Cerca di evitare troppa annidazione. Se le subquery diventano troppo complesse, pensa a spostarle in FROM o a creare tabelle temporanee.

Esempi di utilizzo

Dai, vediamo ancora qualche caso interessante.

Esempio 3: Numero di corsi per ogni studente

Mostriamo una tabella dove per ogni studente si vede il numero di corsi a cui è iscritto. La tabella enrollments è collegata agli studenti tramite student_id:

student_id course_id
1 201
1 202
2 201
3 203

Codice SQL:

SELECT
    s.name AS student_name,
    (
        SELECT COUNT(*) 
        FROM enrollments
        WHERE enrollments.student_id = s.student_id
    ) AS course_count
FROM 
    students s;

Qui la subquery conta il numero di record nella tabella enrollments per ogni studente.

Esempio 4: Flag "eccellente" per ogni studente

Vediamo se uno studente è eccellente. Diciamo che il criterio per essere "eccellente" è avere tutti i voti pari a 5.

Codice SQL:

SELECT
    s.name AS student_name,
    (
        SELECT CASE 
            WHEN MIN(g.grade) = 5 THEN 'Eccellente'
            ELSE 'Non eccellente'
        END
        FROM grades g
        WHERE g.student_id = s.student_id
    ) AS status
FROM 
    students s;

Qui si usa una CASE annidata per assegnare lo status "Eccellente" solo agli studenti che hanno tutti i voti pari a 5.

Ottimizzazione delle subquery in SELECT

Abbiamo già detto che la performance può essere un problema. Ecco qualche dritta per migliorarla:

  1. Usa gli indici. Se le subquery filtrano dati, assicurati che le colonne usate abbiano un indice.
  2. Fai cache dei risultati. A volte conviene spostare le subquery in una VIEW o in tabelle temporanee.
  3. Meno annidamento. Non esagerare con le subquery annidate, se puoi usa un approccio più semplice.

Le subquery in SELECT aprono un sacco di possibilità per calcoli e analisi dei dati. Anche se possono essere pesanti, se le ottimizzi bene rendono SQL molto più espressivo e flessibile. Quindi non aver paura di sperimentare e trovare i tuoi modi per migliorare le query!

Commenti
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION