Visualizzazione risultati 1 fino 5 di 5

Discussione: Query SQL.

  1. #1
    Guest

    Predefinito Query SQL.

    Ciao a tutti. A breve avrò un colloquio su sql. Avendolo studiato 2 anni fa all'università, lo stavo rispolverando, e devo dire che molte cose le ricordo bene.
    Ho un dubbio su una query.

    Questo è il DB:

    Programmi(Codice,
NomeProgramma,
Rete,
Tipologia)
    Artisti(CProgramma,
NomeArt)
    Sondaggi(CodProg,
Auditel)

    Questa è la query:

    Restuire 
i nomi
 dei
 programmi
 con 
almeno 
due 
artisti.

    Ecco la mia soluzione:

    A:
    SELECT count(NomeArt) as numArtisti
    FROM Artisti
    GROUP BY c.Programma
    HAVING numArtisti >=2

    SELECT NomeProgramma
    FROM A,Programmi P
    WHERE P.Codice IN A


    La soluzione dell'esercizio, è invece:

    SELECT
DISTINCT
NomeProgramma
    FROM Programmi
P,
Artisti
A1,
Artisti
A2
    WHERE P.Codice
=
A1.CProgramma
AND
    P.Codice
=
A2.CProgramma
AND
    A1.NomeArt
>
A2.NomeArt

    che onestamente non mi piace, forse perchè non riesco a comprenderla. Me la potreste spiegare perchè utilizza questa soluzione? Grazie mille

  2. #2
    L'avatar di dementialsite
    dementialsite non è connesso Super Moderatore
    Data registrazione
    19-10-2004
    Residenza
    fuori Padova
    Messaggi
    5,046

    Predefinito

    La query che hai postato funziona in questo modo: prima viene creata una "vista" che comprende tutti i record di Programmi giustapposti a quelli di Artisti, e ancora giustapposti a quelli di Artisti (in altre parole, il prodotto cartesiano delle tre tabelle). Questa vista viene poi filtrata per selezione, mantenendo:

    - prima solo i record che hanno il codice del Programma nella prima copia di Artisti ("join" tra Programmi e Artisti)
    - poi solo i record che hanno il codice del Programma anche nella seconda copia di Artisti ("join" tra Programmi, A1 e A2)
    - infine, quelli che hanno il nome della prima copia di Artisti "seguente" a quello della seconda copia di Artisti

    Per questo motivo la query funziona, perché se un Programma fosse curato da un solo Artista verrebbe escluso dal terzo dei filtri di cui sopra: la "vista" filtrata al secondo livello avrebbe infatti solo una riga con il riferimento al Programma e il doppio riferimento all'Artista.

    A dire il vero, la query non funziona poi così bene: se gli Artisti di un programma fossero tre, il risultato comprenderebbe tre record (primo artista con secondo, primo con terzo, e secondo con terzo). Per questo motivo serve la clausola DISTINCT...

    Come soluzione, è decisamente più intuitiva questa (a te scoprire come funziona...):
    Codice:
    SELECT NomeProgramma
    FROM Programmi
    WHERE Codice IN (
       SELECT CProgramma
       FROM Artisti
       GROUP BY CProgramma
       HAVING COUNT(numArtisti) >= 2
    )
    Se non ti è chiara la spiegazione, prova a seguirla utilizzando i dati concreti del tuo database... dovrebbe succedere più o meno quanto ti ho descritto sopra.

    Stammi bene...
    Le questioni tecniche hanno risposte migliori nel forum pubblico, non trovi?

    When you don't know your next step... improvise

    ALTERVISTA WANTS YOU!
    Vuoi diventare moderatore su AlterVista? Scopri come...

  3. #3
    Guest

    Predefinito

    Vediamo se ho capito... la tua mi sembra molto chiara... ne ho fatta un altra.. dimmi se va bene

    Restituire i nomi dei programmi con un solo artista

    SELECT NomeProgramma
    FROM Programmi
    WHERE Codice IN(
    SELECT CProgramma
    FROM Artisti
    GROUP BY CProgramma
    HAVING count(NomeArtista)=1

  4. #4
    L'avatar di binarysun
    binarysun non è connesso Utente storico
    Data registrazione
    02-07-2004
    Messaggi
    2,017

    Predefinito

    La soluzione dell'esercizio funziona, ma è concettualmente sbagliata.

    La soluzione canonicamente corretta dovrebbe essere semplicemente
    SELECT Programmi.NomeProgramma
    FROM Programmi Inner join Artisti ON Programmi.Codice = Artisti.Codice
    GROUP BY Programmi.CodiceProgramma,Programmi.NomeProgramma
    HAVING count(*) >=2

    Il raggruppamento solo su nomeprogramma se è sicuro che nomeprogramma è univoco, quindi se è impostato a univoco.
    In questoc aso immagino che la chiave della tabella programmi sia codice programma.
    "L'intelligenza è una pianta che va curata continuamente.
    Dovreste vedere com'è bello, il mio bonsai."
    Rat-man®

    [Gradient Text]
    [Su che server sei?]
    ->flickr

  5. #5
    L'avatar di zingus
    zingus non è connesso Utente giovane
    Data registrazione
    02-09-2003
    Messaggi
    83

    Predefinito

    Punto Binarysun. Palla al centro.

    Citazione Originalmente inviato da binarysun Visualizza messaggio
    La soluzione dell'esercizio funziona, ma è concettualmente sbagliata.
    Funziona a botte di prodotti cartesiani filtrati mi pare. Scala (male) fino a due artisti, ma dovendo espandere a 3 o a 4 va ripensata da zero.

    Riguardo all'altra soluzione riportata...
    Usa delle suquery: "SELECT ... WHERE X = (SELECT ...)"

    Concettualmente, usare delle subquery, è sempre meglio di non usarle e di fare due query. (come molti fanno... e se non ne avete mai incontrati, li incontrerete)

    Ma ci sono motivi (1) storici e (2) di performance per cui in fase di colloquio le soluzioni con subquery sono solitamente guardate storte.

    (1) Molti DB non supportavano le subquery del tutto. Ora quei db o sono stati aggiornati per supportarle o sono morti. Esistono sempre scenari legacy, ma, nei casi tipici e ragionevoli, la presenza o meno delle subquery non dovrebbere più essere un problema.

    (2) Le subquery vengono viste (a torto o a ragione dipende dalle engine e dalle versioni delle engine) come causa di rallentamenti nella esecuzione delle query.

    Detto questo: se mi venisse in mente, come prima soluzione, una soluzione che usa una subquery, la presenterei al volo. Ma aggiungerei un sacco di distinguo sul fatto che si può fare in altri modi. E magari proporrei anche una versione senza subquery. (con quantificatori tipo COUNT o SUM, come quella di binarysun)
    Ultima modifica di zingus : 30-10-2012 alle ore 03.45.12

Regole di scrittura

  • Non puoi creare nuove discussioni
  • Non puoi rispondere ai messaggi
  • Non puoi inserire allegati.
  • Non puoi modificare i tuoi messaggi
  •