Da neofita: come funziona una subquery correlata (vedi esempio)

di il
7 risposte

Da neofita: come funziona una subquery correlata (vedi esempio)

Ciao a tutti,

nel libro “DATABASE - I MANGA DELLE SCIENZE” (per iniziare a conoscere il magico mondo sql) trovo queste due tabelle:

   TABELLA PRODOTTI
   
   CODICE PRODOTTO | NOME PRODOTTO | PREZZO UNIT.
   ----------------------------------------------
   101             | MELONE        | 800Au
   102             | FRAGOLA       | 150Au
   103             | MELA          | 120Au
   104             | LIMONE        | 200Au
   
   TABELLA RISULTATI DI VENDITA
   
   N. REGISTRAZIONE | CODICE PRODOTTO | QUANTITA'
   ----------------------------------------------
   1101             | 101             | 1.100
   1101             | 102             | 300
   1102             | 103             | 1.700
   1103             | 104             | 500
   1104             | 101             | 2.500
   1105             | 103             | 2.000
   1105             | 104             | 700
   

E questa query, che prevede una subquery (correlata):

   SELECT *
   FROM RISULTATI_VENDITA U
   WHERE QUANTITA >
    ( 
     SELECT AVG(QUANTITA) 
     FROM RISULTATI_VENDITA
     WHERE CODICE_PRODOTTO = U.CODICE_PRODOTTO
    );

Il risultato è il seguente:

     N. REGISTRAZIONE | CODICE PRODOTTO | QUANTITA'
    ----------------------------------------------
    1104             | 101             | 2.500
    1105             | 103             | 2.000
    1105             | 104             | 700

Non capisco:

1) chi dice a sql che deve iterare la query per ogni riga della tabella? Il “where >”?

2) al primo giro, con codice_prodotto = 101, il risultato ottenuto consisteva nelle righe penultima e terzultima di risultati_vendita, con codice 102, tutte tranne se stessa, con codice 103 di nuovo la penultima e terzultima, con codice 104 tutte tranne se stessa e quella relativa al codice prodotto 102. Non capisco quindi come ha ottenuto il risultato finale.

Grazie!

Alessandro

7 Risposte

  • Re: Da neofita: come funziona una subquery correlata (vedi esempio)

    Una query che ha al suo interno una subquery viene svolta seccondo un ordine di precedenza dalla più interna (la subquery) a quella più esterna (la query).
    Quindi viene prima svolta (in memoria) il calcolo della media AVG(QUANTITA) e confrontata per ciascun CODICE_PRODOTTO = U.CODICE_PRODOTTO in quanto la query esterna (denominata U) prende in esame solo quelli ove la QUANTITA è maggiore della media (fornita dalla subquery).

  • Re: Da neofita: come funziona una subquery correlata (vedi esempio)

    Grazie willy55, posso approfittarne per chiederti come bisogna ragionare.

    Riprendo la query:

       SELECT *
       FROM RISULTATI_VENDITA U
       WHERE QUANTITA >
        ( 
         SELECT AVG(QUANTITA) 
         FROM RISULTATI_VENDITA
         WHERE CODICE_PRODOTTO = U.CODICE_PRODOTTO
        );

    Prendo prima quella interna:

    SELECT AVG(QUANTITA) 
         FROM RISULTATI_VENDITA
         WHERE CODICE_PRODOTTO = U.CODICE_PRODOTTO

    E si parte dal primo codice prodotto di U, cioè 101.

    Nella tabella risultati_vendita ho il codice prodotto 101 in corrispondenza delle quantità 1.100 e 2.500, la cui media fa 1.800. E' questo il valore che passo alla query esterna o passo a codice prodotto 102? Perchè nella prima ipotesi cosa ne farei della seguente query?

     SELECT *
       FROM RISULTATI_VENDITA U
       WHERE QUANTITA > 1800

    Mettiamo caso che non passo 1800 alla query esterna, ma accantono 1800 e passo al codice prodotto 102 e così via?

    Torno alle mie domande:

    1) chi dice a sql che deve iterare la query per ogni riga della tabella? Il “where >”?

    2) come fa la query nel suo complesso passo-passo?

    Grazie

  • Re: Da neofita: come funziona una subquery correlata (vedi esempio)

    Cerco di descriverti il processo passo passo.
    Il codice 101 ha, nella tabella RISULTATI_VENDITA, le QUANTITA' con valori di 1.100 e 2.500 su cui viene effettuata la media, il cui risultato è 1.800 che nella query esterna viene confrontato con i valori presenti per lo specifico CODICE_PRODOTTO = U.CODICE_PRODOTTO ed estratti i valori ove la QUANTITA' supera la media (1.800) in questo caso esclusivamente 2.500.
    Quindi viene analizzato il codice 102 (con una singola QUANTITA' pari a 300) che nella media con se stesso (quindi sempre 300) viene passato alla query esterna, ma essendo la QUANTITA' non superiore alla sua media (in quanto uguali, 300) non viene estratto.
    Successivamente si passa al codice 103 ove le QUANTITA' hanno valori di 1.700 e 2.000 e la cui media è 1.850 di conseguenza l'unico valore superiore alla media è 2.000 che viene estratto.
    Infine viene elaborato il codice 104 ove le QUANTITA' hanno valori di 500 e 700, e calcolata la media pari a 600, ne consegue che viene estratto 700 in quanto unico valore superiore alla media..
    Ed è per questo che ottieni i tre valori del risultato.  

  • Re: Da neofita: come funziona una subquery correlata (vedi esempio)

    10/04/2023 - willy55 ha scritto:



    Ed è per questo che ottieni i tre valori del risultato.  

    Ti ringrazio, ora ho capito, finalmente, come funziona la query.

    Toglimi però quest'ultima curiosità: mi accorgo che itera per ogni codice prodotto perchè c'è la condizione where codice_prodotto = u.codice_prodotto?

    Grazie

  • Re: Da neofita: come funziona una subquery correlata (vedi esempio)

    È la stessa domanda che hai fatto all'inizio, quindi ancora non hai proprio compreso pienamente.

    La WHERE funziona da filtro, non ha alcun nesso con l'iterazione. Il ciclo è avviato e gestito dalla SELECT  

  • Re: Da neofita: come funziona una subquery correlata (vedi esempio)

    11/04/2023 - NEOFSQL ha scritto:


    Toglimi però quest'ultima curiosità: mi accorgo che itera per ogni codice prodotto perchè c'è la condizione where codice_prodotto = u.codice_prodotto?

    No, come evidenziato anche da Oregon, è la SELECT * (della query principale) che seleziona tutti i record, dalla tabella (FROM RISULTATI_VENDITA U) in base alla condizione WHERE QUANTITA > il contenuto della subquery.
    Nella subquery si effettua una nuova SELECT con la funzione di aggregazione AVG(QUANTITA) che calcola la media aritmetica dell'attributo numerico prescelto (QUANTITA) e restituisce un valore in corrispondenza di un gruppo di valori o dei valori che formano una colonna di una tabella contenuta in un database; in questo caso la subquery agisce sempre su medesima tabella FROM RISULTATI_VENDITA con la condizione  WHERE CODICE_PRODOTTO = U.CODICE_PRODOTTO ove U fa riferimento alla tabella della query principale fornito alla subquery.

  • Re: Da neofita: come funziona una subquery correlata (vedi esempio)

    Per comprendere la query con al suo interno la subquery si possono implementare le singole  operazioni in SQL al fine di ottenere il medesimo risultato finale.

    Ad esempio partendo dalla tabella iniziale

    Tabella_Risultati_Vendita

    Numero_Registrazione

    Codice_Prodotto

    Quantità

    1101

    101

    1100

    1101

    102

    300

    1102

    103

    1700

    1103

    104

    500

    1104

    101

    2500

    1105

    103

    2000

    1105

    104

    700

    Si determina la media della Quantità venduta per ciascun Codice_ Prodotto, con una query similare:

    SELECT Risultati_Vendita.Codice_Prodotto, Avg(Risultati_Vendita.Quantità) AS MediaDiQuantità
    FROM Risultati_Vendita
    GROUP BY Risultati_Vendita.Codice_Prodotto;

    che denominiamo QueryCalcoloMedia e si ottengono i seguenti valori della media (i quali corrispondono al processo svolto dalla subquery).

    QueryCalcoloMedia

    Codice_Prodotto

    MediaDiQuantità

    101

    1800

    102

    300

    103

    1850

    104

    600

    Dopodiché, per conoscere quali prodotti nelle vendite hanno una Quantità maggiore della sua media è sufficiente mettere in relazione (JOIN) la tabella iniziale con la query precedente.

    SELECT Risultati_Vendita.Codice_Prodotto, Risultati_Vendita.Quantità, QueryCalcoloMedia.MediaDiQuantità
    FROM Risultati_Vendita INNER JOIN QueryCalcoloMedia ON Risultati_Vendita.Codice_Prodotto = QueryCalcoloMedia.Codice_Prodotto
    WHERE (((Risultati_Vendita.Quantità)>[QueryCalcoloMedia]![MediaDiQuantità]));

    Il cui risultato finale è:

    QueryQuantitàMaggiore Media

    Codice_Prodotto

    Quantità

    MediaDiQuantità

    101

    2500

    1800

    103

    2000

    1850

    104

    700

    600

    Ove si può notare, nel Venduto, di ciascun Codice_Prodotto, la Quantità maggiore della sua media, che corrisponde ai dati estratti all’originaria query e subquery del post in oggetto.

Devi accedere o registrarti per scrivere nel forum
7 risposte