Caro Edoardo,
ti sei complicato un po’ la vita perché si poteva tranquillamente assumere che la tabella esami contenga solo gli esami verbalizzati, quindi un solo voto per materia e maggiore di 18.
Ad ogni modo ho capito la logica della tua query, che presenta però alcuni problemi.
Problema 1 (Vista VotoMassimoPerStudenteInUnEsame)
La vista VotoMassimoPerStudenteInUnEsame contiene solo l’attributo Max(voto), non tiene traccia della matricola dello studente, né del codice del corso. Va inoltre ridenominato l’attributo MAX(voto) per poterlo richiamare in nuove query.
Basta semplicemente riscrivere come:
CREATE VIEW VotoMassimoPerStudenteInUnEsame AS
SELECT Matricola_studente, Codice_corso, MAX(Voto) as VotoMax
FROM Esame
GROUP BY Matricola_studente, Codice_corso
Problema 2 (Vista EsamiSuperatiPerStudente)
Il tuo dubbio è legittimo infatti non succede quello che speri.
Innanzitutto, stai confrontando un attributo con il nome di una vista (e quindi con una tabella) e non con un attributo della vista e questo non ha senso. Tu vuoi confrontare l’attributo Voto con l’attributo VotoMax.
Quando una query coinvolge attributi che appartengono a più tabelle è sempre necessario fare un Join (oppure utilizzare una subquery). Ad esempio potresti riscrivere così:
CREATE VIEW EsamiSuperatiPerStudente AS
SELECT Matricola_studente, SUM(NumeroEsamiSuperatiPerCorso) AS EsamiSuperati
FROM(
ti sei complicato un po’ la vita perché si poteva tranquillamente assumere che la tabella esami contenga solo gli esami verbalizzati, quindi un solo voto per materia e maggiore di 18.
Ad ogni modo ho capito la logica della tua query, che presenta però alcuni problemi.
Problema 1 (Vista VotoMassimoPerStudenteInUnEsame)
La vista VotoMassimoPerStudenteInUnEsame contiene solo l’attributo Max(voto), non tiene traccia della matricola dello studente, né del codice del corso. Va inoltre ridenominato l’attributo MAX(voto) per poterlo richiamare in nuove query.
Basta semplicemente riscrivere come:
CREATE VIEW VotoMassimoPerStudenteInUnEsame AS
SELECT Matricola_studente, Codice_corso, MAX(Voto) as VotoMax
FROM Esame
GROUP BY Matricola_studente, Codice_corso
Problema 2 (Vista EsamiSuperatiPerStudente)
Il tuo dubbio è legittimo infatti non succede quello che speri.
Innanzitutto, stai confrontando un attributo con il nome di una vista (e quindi con una tabella) e non con un attributo della vista e questo non ha senso. Tu vuoi confrontare l’attributo Voto con l’attributo VotoMax.
Quando una query coinvolge attributi che appartengono a più tabelle è sempre necessario fare un Join (oppure utilizzare una subquery). Ad esempio potresti riscrivere così:
CREATE VIEW EsamiSuperatiPerStudente AS
SELECT Matricola_studente, SUM(NumeroEsamiSuperatiPerCorso) AS EsamiSuperati
FROM(
SELECT E.Matricola_studente, COUNT(*) AS NumeroEsamiSuperatiPerCorso
FROM Esame E JOIN votomassimoperstudenteinunesame V ON E.Matricola_studente=V.Matricola_studente
FROM Esame E JOIN votomassimoperstudenteinunesame V ON E.Matricola_studente=V.Matricola_studente
WHERE Voto >= 18 AND Voto = MAX(Voto)
GROUP BY E.Matricola_studente, E.Codice_corso) as N_esami
GROUP BY Matricola_studente
Problemi minori:
* la sintassi SQL richiede che le subquery siano racchiuse tra parentesi e che alle subquery nella clausola FROM sia assegnato un alias.
* In sql non si usa il simbolo “ ==” come operatore di confronto ma semplicemente “=“, visto che non è usato come operatore di assegnamento
* Alcuni nomi di attributi non sono scritti esattamente come nello schema (e.g. codice_c invece di codice_corso)
Commenti generali
La tua query, a meno dei suddetti errori, ha una logica e semantica corrette, ma non è molto leggibile e abusa delle viste che è preferibile non utilizzare come mero strumento di programmazione.
Mantenendo il tuo approccio di confrontare i due conteggi puoi provare come esercizio ad utilizzare una forma molto più snella che fa uso del predicato having sui gruppi.
GROUP BY E.Matricola_studente, E.Codice_corso) as N_esami
GROUP BY Matricola_studente
Problemi minori:
* la sintassi SQL richiede che le subquery siano racchiuse tra parentesi e che alle subquery nella clausola FROM sia assegnato un alias.
* In sql non si usa il simbolo “ ==” come operatore di confronto ma semplicemente “=“, visto che non è usato come operatore di assegnamento
* Alcuni nomi di attributi non sono scritti esattamente come nello schema (e.g. codice_c invece di codice_corso)
Commenti generali
La tua query, a meno dei suddetti errori, ha una logica e semantica corrette, ma non è molto leggibile e abusa delle viste che è preferibile non utilizzare come mero strumento di programmazione.
Mantenendo il tuo approccio di confrontare i due conteggi puoi provare come esercizio ad utilizzare una forma molto più snella che fa uso del predicato having sui gruppi.
Faccio di nuovo presente che questo approccio non esclude che uno studente abbia sostenuto esami fuori dal proprio piano di studio.
Spero di essere stata chiara. Rimango a disposizione per ulteriori dubbi e incoraggio i tuoi compagni a commentare a loro volta.
Spero di essere stata chiara. Rimango a disposizione per ulteriori dubbi e incoraggio i tuoi compagni a commentare a loro volta.