PDA

View Full Version : [SQL] esercizi


cletopolonia
16-07-2007, 09:27
Si consideri il seguente schema relazionale:
Clienti(codifisc, nome, indirizzo, nazione)
Ordini(oid, codfisc,data_consegna, prezzo)
Pezzi(pid, categoria, prezzo)
PezziVenduti(pid, oid)

esprimere in SQL le seguenti interrogazioni:
a) "per ogni nazione, trovare i nomi dei clienti che hanno ordinato pezzi di categoria 3, prima del 12giugno"
b) "trovare i nomi dei clienti che hanno speso meno di tutti gli altri"

le chiavi primarie sono sottolineate. gli attributi con nomi uguali in differenti relazioni sono legati mediante vincoli di chaive esterna.

grazie..

cionci
16-07-2007, 10:43
Mi sembra abbastanza semplice...prova a farlo e poi facci vedere dove sei arrivato.
Ad esempio per la a) basta una query di selezione sui pezzi da mettere nel from (per filtrare data e tipo) e poi un group by...

cletopolonia
17-07-2007, 08:32
a)
SELECT C.nome
FROM clienti C, ordini O
WHERE C.codFisc = O.codFisc IN
( SELECT O.data_consegna
FROM ordini O, pezzi P, pezziVenduti PV
WHERE O.data consegna < "12 luglio" AND O.oid=PV.oid )
GROUP BY C.nazione

b)
SELECT C.nomi, SUM(O.prezzo) AS TotOrdini
FROM clienti C, ordini O
HAVING C.codFisc=O.codFisc AND MIN(TotOrdini)

cletopolonia
18-07-2007, 20:04
up-help

cionci
18-07-2007, 20:24
La a) va quasi bene...se raggruppi per nazione dopo non puoi selezionare i nomi, quindi quel "per nazione" presente nel testo io lo interpreterei come un ORDER BY nazione. Nella sottoquery ti sei scordato di fare il filtraggio per categoria (che deve essere 3).

Sulla seconda non ci siamo. HAVING ha effetto solo se fai un raggruppamento e la devi usare per indicare condizioni sulle funzioni di aggregazione aventi come parametri attributi non presenti nel group by e quindi non selezionabili.
A questo punto di consiglio di "andare per livelli"...prima analizziamo il testo. Il testo non sembra proprio completo. Cosa vuol dire trovare "trovare i clienti che hanno spedo meno di tutti gli altri" ? Quanti ? 1, 10, 100 ? La domanda quindi non è completa. Sarebbe carino trovarne 1, è una cosa non banale e molto simpatica da fare senza costrutti specifici dei vari dialetti SQL.

Quindi come detto andiamo per gradi.
La prima query da fare è: trovare la somma degli ordini di tutti i clienti (e questo è un raggruppamento per codfisc con una funzione di aggregazione somma sul prezzo dei prodotti ordinati).

Dopo di questo magari dimmi quanti e quali i nomi si vuole tirare fuori dalla lista.

cletopolonia
19-07-2007, 08:33
opps hai ragione, la mia memoria illimitata di 4kb ogni tanto fa cilecca..:doh:
Allora la prima dovrebbe essere +o- così:

a)
SELECT C.nome
FROM clienti C, ordini O
WHERE C.codFisc = O.codFisc IN
( SELECT O.data_consegna
FROM ordini O, pezzi P, pezziVenduti PV
WHERE O.data consegna < "12 luglio" AND O.oid=PV.oid
and PV.pid=P.pid AND P.categoria = 3) <= è giusta???
ORDER BY C.nazione

b)
SELECT C.nome, SUM(O.prezzo) AS totOrdini
FROM Clienti C, Ordini O
WHERE C.codfisc = O.codfisc
ORDER BY totOrdini DESC


- ammesso che questo codice sia giusto, penso che 10 bastino, ma sarei curioso di vedere come si fa a vedere il cliente che ha speso meno, sempre che non sia troppo complicato..
- posso usare SUM al di fuori della SELECT??

Ti ringrazio x l'aiuto ma ora non so + cosa fare.
Mi fai vedere te la soluzione..

ceschi
19-07-2007, 13:48
la prima la farei così

SELECT C.Nazione, C.Nome
FROM Clienti C, Ordini O, Pezzi P, PezziVenduti PV
WHERE C.CodFisc = O.CodFisc AND
O.Data_Consegna <= '12/07/2007'
O.Oid = PV.Oid AND
PV.Pid = P.Pid AND
P.Categoria = 3
Order BY C.Nazione, C.Nome

la seconda

SELECT TOP 10 C.Nome, SUM(O.Prezzo)
FROM Clienti C, Ordini O
WHERE C.CodFisc = O.COdFisc
ORDER BY SUM(O.Prezzo)