PDA

View Full Version : [SQL]Errore in una query con GROUP BY


vicus
29-05-2006, 14:33
Il DB è composto da tre tabelle:
Ordine(td,nome,posti,data),Piatti(id,descrizione),Portate(id,descrizione) e da una tabella di appoggio Dettagli(idOrd,idPiatto,idPortata).
La query è la seguente:

SELECT Ordine.nome, SUM(Ordine.posti), Piatti.descrizione, Portate.descrizione
FROM 'le quattro tabelle unite col INNER JOIN sul codice'
WHERE Ordine.data=<input>
GROUP BY portate.descrizione,piatti.descrizione

Ma mi da questo errore:
[Microsoft][ODBC SQL Server Driver][SQL Server]La colonna 'ordini.nome' non è valida nell'elenco di selezione perché non è inclusa né in una funzione di aggregazione né nella clausola GROUP BY.

Come risolvo il mio problema?

Duncan
29-05-2006, 15:04
Hai messo una funzione di aggregazione sulla select


SELECT Ordine.nome, SUM(Ordine.posti), Piatti.descrizione, Portate.descrizione

quindi nella group by

devi mettere gli altri tre campi, altrimenti ti da errore


GROUP BY Ordine.nome, Piatti.descrizione, Portate.descrizione

vicus
29-05-2006, 15:13
Non posso fare così perchè ho bisogno della somma di tutti gli ordini che hanno quel piatto in quella portata.
Questo non è un problema perchè la somma la potrei farla dopo però nemmeno la query
SELECT Ordine.nome, Ordine.posti, Piatti.descrizione, Portate.descrizione
FROM 'le quattro tabelle unite col INNER JOIN sul codice'
WHERE Ordine.data=<input>
GROUP BY portate.descrizione,piatti.descrizione

funziona anche se non c'è la funzione di aggregazione SUM().

vicus
29-05-2006, 15:29
Errata corrige:
leggendo una dispensa mi sono ricordato che con il GROUP BY si una HAVING quindi:
SELECT Ordine.nome, Ordine.posti, Piatti.descrizione, Portate.descrizione
FROM 'le quattro tabelle unite col INNER JOIN sul codice'
GROUP BY portate.descrizione,piatti.descrizione
HAVING Ordine.data=<input>

ma comunque non funziona :( e l'errore si è esteso alla data perchè non fa parte ne di una funzione di aggregazione ne nella clausola GROUP BY.

Duncan
29-05-2006, 15:42
Errata corrige:
leggendo una dispensa mi sono ricordato che con il GROUP BY si una HAVING quindi:
SELECT Ordine.nome, Ordine.posti, Piatti.descrizione, Portate.descrizione
FROM 'le quattro tabelle unite col INNER JOIN sul codice'
GROUP BY portate.descrizione,piatti.descrizione
HAVING Ordine.data=<input>

ma comunque non funziona :( e l'errore si è esteso alla data perchè non fa parte ne di una funzione di aggregazione ne nella clausola GROUP BY.

Puoi usare where od having a seconda di quello che devi fare

DvL^Nemo
29-05-2006, 15:45
Prova cosi'


SELECT DISTINCT Ordine.nome, Ordine.posti, Piatti.descrizione, Portate.descrizione
FROM 'le quattro tabelle unite col INNER JOIN sul codice'
WHERE Ordine.data=<input>

Duncan
29-05-2006, 15:47
Non posso fare così perchè ho bisogno della somma di tutti gli ordini che hanno quel piatto in quella portata.
Questo non è un problema perchè la somma la potrei farla dopo però nemmeno la query
SELECT Ordine.nome, Ordine.posti, Piatti.descrizione, Portate.descrizione
FROM 'le quattro tabelle unite col INNER JOIN sul codice'
WHERE Ordine.data=<input>
GROUP BY portate.descrizione,piatti.descrizione

funziona anche se non c'è la funzione di aggregazione SUM().

Se devi fare la somma di tutti gli ordini non puoi mettere anche Ordine.nome nella select, se ho capito bene com'è strutturato il DB...

Ordine.nome cos'è? Nella tabella ordini cosa c'è?

Duncan
29-05-2006, 15:48
Prova cosi'


Ma così dopo riscia di non poter fare la somma delle protate mi sembra

DvL^Nemo
29-05-2006, 15:52
Hai ragione, mi sono limitato a leggere l'ultima query ( dove non c'era traccia del sum ).. cmq ci sarebbe da vedere come e' struturato il DB per capire cosa serve e cosa fare..
Ciao !

vicus
29-05-2006, 15:54
Se devi fare la somma di tutti gli ordini non puoi mettere anche Ordine.nome nella select, se ho capito bene com'è strutturato il DB...

Ordine.nome cos'è? Nella tabella ordini cosa c'è?

Ordine(id,nome,posti,data)

posso rinunciare alla somma ma questa dovrebbe funzionare
SELECT Ordine.nome, Ordine.posti, Piatti.descrizione, Portate.descrizione
FROM 'le quattro tabelle unite col INNER JOIN sul codice'
GROUP BY portate.descrizione,piatti.descrizione
HAVING Ordine.data=<input>ed invece non va.

Duncan
29-05-2006, 15:54
Hai ragione, mi sono limitato a leggere l'ultima query ( dove non c'era traccia del sum ).. cmq ci sarebbe da vedere come e' struturato il DB per capire cosa serve e cosa fare..
Ciao !


A leggere la prima query che ha scritto la soluzione è non mettere Ordine.nome nell'elenco della select, ma bisogna vedere se gli serve o meno quella colonna...

Duncan
29-05-2006, 15:56
Ordine(id,nome,posti,data)

posso rinunciare alla somma ma questa dovrebbe funzionare
SELECT Ordine.nome, Ordine.posti, Piatti.descrizione, Portate.descrizione
FROM 'le quattro tabelle unite col INNER JOIN sul codice'
GROUP BY portate.descrizione,piatti.descrizione
HAVING Ordine.data=<input>ed invece non va.


C'è un errore di fondo, così non ti funzionerà mai, le colonne che specifichi nella clausola select le devi mettere anche nella group by a meno che non sia usate, nella select stessa, in funzioni di aggregazione ([i]SUM, COUNT, AVG ecc)

DvL^Nemo
29-05-2006, 15:57
Ordine(id,nome,posti,data)

posso rinunciare alla somma ma questa dovrebbe funzionare
SELECT Ordine.nome, Ordine.posti, Piatti.descrizione, Portate.descrizione
FROM 'le quattro tabelle unite col INNER JOIN sul codice'
GROUP BY portate.descrizione,piatti.descrizione
HAVING Ordine.data=<input>ed invece non va.

E allora se non ti serve la somma prova questa che funziona


SELECT DISTINCT Ordine.nome, Ordine.posti, Piatti.descrizione, Portate.descrizione
FROM 'le quattro tabelle unite col INNER JOIN sul codice'
WHERE Ordine.data=<input>

vicus
29-05-2006, 15:59
Non posso usare usare funzioni di aggregazione, togliere il nome o includerlo nel group by.
Mi dovro inventare qualcosa costituito da più query.

DvL^Nemo
29-05-2006, 16:01
Esegui la query che ti ho scritto e vediamo se funziona :p
Tanto hai detto il SUM lo recuperi da altre parti..
Ciao !

Duncan
29-05-2006, 16:02
E allora se non ti serve la somma prova questa che funziona



Si con la distinct funziona, ed anche con la group by, solo che dopo non è possible usare ordine.posti per sommare, perchè i valori duplicati sono stati eliminati dalla distinct o raggruppati dalla group by


IMHO la query giusta è


SELECT SUM(Ordine.posti), Piatti.descrizione, Portate.descrizione
FROM 'le quattro tabelle unite col INNER JOIN sul codice'
WHERE Ordine.data=<input>
GROUP BY portate.descrizione,piatti.descrizione

A che ti serve Ordine.nome? Cosa c'è scritto dentro?

Duncan
29-05-2006, 16:04
Scusa ma nella tabella ordine cosa c'è dentro?


Tabella Ordine

id = chiave tabella?
nome = ???
posti = numero di portate ordinate?
data = data ordine



Spiegami un po', perchè altrimenti mi riesce difficile cosa c'è dentro

DvL^Nemo
29-05-2006, 16:06
In effetti quell'ordine.nome e' strano, la mia "preoccupazione" e' che sia strutturato male il DB, perche' se il group by va utilizzato in una certe maniera c'e' un motivo..
Ciao !

Duncan
29-05-2006, 16:09
In effetti quell'ordine.nome e' strano, la mia "preoccupazione" e' che sia strutturato male il DB, perche' se il group by va utilizzato in una certe maniera c'e' un motivo..
Ciao !


Infatti è anche la mia paura, se devi sommare Ordine.posti, se il DB è corretto i casi sono due

Non di interessa nulla di Ordine.Nome
O lo metti in Group by e select

vicus
29-05-2006, 16:17
Allora
tabella ordini:
nome: chi ha fatto l'ordine
posti: per quante persone
data: per quando ha prenotato

A me serve sapere per quante persone e in quali ordini serve un piatto di un dato giorno.

SELECT Ordine.nome, Ordine.posti, Piatti.descrizione, Portate.descrizione
FROM 'le quattro tabelle unite col INNER JOIN sul codice'
GROUP BY portate.descrizione,piatti.descrizione
HAVING Ordine.data=<input> Questa in Access funziona.

Sono uno studente e questo è il primo DB serio che faccio quindi è possibile che sia fatto male daltronde lo rifatto solo 2 volte.

Duncan
29-05-2006, 16:32
Allora
tabella ordini:
nome: chi ha fatto l'ordine
posti: per quante persone
data: per quando ha prenotato


Ok, e cosa hanno ordinato dove sta? nella tabella dettagli?

A me serve sapere per quante persone e in quali ordini serve un piatto di un dato giorno.

ok


select Ordine.Nome, SUM(Ordine.posti), Piatto.descrizione, Portate.descrizione
Portate.descrizione
FROM 'le quattro tabelle unite col INNER JOIN sul codice'
WHERE Ordine.data=<input>
GROUP BY Ordine.Nome, portate.descrizione,piatti.descrizione


con questa query ti calcoli cosa è stato ordinato per ordine (ammettendo che Ordine.nome sia distinto tra ordine ed ordine


SELECT Ordine.nome, Ordine.posti, Piatti.descrizione, Portate.descrizione
FROM 'le quattro tabelle unite col INNER JOIN sul codice'
GROUP BY portate.descrizione,piatti.descrizione
HAVING Ordine.data=<input> Questa in Access funziona.


Sinceramente ad occhio non riesco nemmeno a capire come sia possibile che funzioni, IN SQL quello che è specificato nella select se non è in una funzione di aggregazione deve essere anche nella group by


Sono uno studente e questo è il primo DB serio che faccio quindi è possibile che sia fatto male daltronde lo rifatto solo 2 volte.

Non ti preoccupare, all'inizio si sbaglia tutti... ed anche poi ;) :D

DvL^Nemo
29-05-2006, 16:42
X scrupolo mi sono rifatto il DB come lo hai scritto te vicus e la query che chiedi e' questa

SELECT Ordine.nome, Ordine.posti
FROM Portate INNER JOIN (Piatti INNER JOIN (Ordine INNER JOIN Dettagli ON Ordine.td = Dettagli.idOrd) ON Piatti.ID = Dettagli.idPiatto) ON Portate.ID = Dettagli.idPortata
GROUP BY Ordine.nome, Ordine.posti, Ordine.data
HAVING (((Ordine.data)="25/05/2005"));

Il db che ho creato e' questo

http://img527.imageshack.us/img527/798/access5iv.jpg

Duncan
29-05-2006, 16:50
X scrupolo mi sono rifatto il DB come lo hai scritto te vicus e la query che chiedi e' questa

SELECT Ordine.nome, Ordine.posti
FROM Portate INNER JOIN (Piatti INNER JOIN (Ordine INNER JOIN Dettagli ON Ordine.td = Dettagli.idOrd) ON Piatti.ID = Dettagli.idPiatto) ON Portate.ID = Dettagli.idPortata
GROUP BY Ordine.nome, Ordine.posti, Ordine.data
HAVING (((Ordine.data)="25/05/2005"));

Il db che ho creato e' questo

http://img527.imageshack.us/img527/798/access5iv.jpg

Giusto.... la sintassi delle join di Access l'ho sempre odiata :)

DvL^Nemo
29-05-2006, 16:59
Se invece vuoi la somma x posti ( da come e' fatto il db non avrebbe senso )

SELECT Ordine.nome, Sum(Ordine.posti) AS SommaDiposti
FROM Portate INNER JOIN (Piatti INNER JOIN (Ordine INNER JOIN Dettagli ON Ordine.td = Dettagli.idOrd) ON Piatti.ID = Dettagli.idPiatto) ON Portate.ID = Dettagli.idPortata
GROUP BY Ordine.nome, Ordine.data
HAVING (((Ordine.data)="25/05/2005"));

Ciao!