Newsgroup: it.comp.software.database
Titolo: [SS7] scrittura query con raggruppamento

Salve a tutti. Devo scrivere una query per SQL Server 7, e con i risultati
vado a riempire una griglia di un applicativo realizzato in VB6. La query la
scrivo come testo dentro il codice VB, e poi tramite ADO la passo alla
connessione. Però ho qualche problema a scrivere la query: fino ad oggi
scrivevo le query a mano nel Query Analyzer e poi le riportavo nel codice
VB, solo che stavolta mi ci sto piantando. Il problema nasce dalla necessità
di raggruppare i dati. Espongo il problema.
La query che ho costruito, cioè quella che viene eseguita da ADO, è la
seguente:
SELECT DATAEFF AS scadenza,
(CAST(NUMFATT AS varchar) + ' ' + SERIEFATT + ' del ' + CONVERT(nvarchar,
DATAFATT, 103)) AS [riferimento fattura],
(CAST(IDCLIENTE AS nvarchar) + ' - ' + RAGSOCCLI) AS cliente,
(CAST(ABICLI AS nvarchar) + ' - ' + DESCRABICLI) AS [banca cliente],
(CASE ISNULL(EMESSO, 0) WHEN 0 THEN 'no' ELSE 'si' END) AS [em.],
(CASE ISNULL(INCASSATO, 0) WHEN 0 THEN 'no' ELSE 'si' END) AS [incass.],
IMPORTO AS importo, (IMPORTO - IMPORTOINCASSATO) AS residuo,
(CASE ISNULL(INSOLUTO, 0) WHEN 0 THEN '' ELSE 'si' END) AS [insol.]
FROM EFFETTI
WHERE DITTA = 1;
Questa query estrae gli effetti di una specifica ditta dalla tabella
Effetti. A parte le parole chiave, i nomi in maiuscolo sono i nomi dei campi
della tabella.
La query così impostata funziona a dovere: i dati sono quelli giusti e la
griglia si riempie correttamente. Gli alias servono per le intestazioni di
colonna della griglia, perché il controllo che .
Il problema è che tra le richieste specifiche del committente c'è anche
l'opzione di raggruppare i record per data, per cliente, o per data e
cliente. Questa è la cosa che non riesco a fare.
Ho tentato di aggiungere una clausola GROUP BY sul campo IDCLIENTE: la
verifica della sintassi del Query Analyzer mi dice che l'struzione è
corretta, ma se tento di eseguirla ricevo il messaggio di errore
"Column 'EFFETTI.DATAEFF' is invalid in the select list because it is not
contained in either an aggregate function or the GROUP BY clause.
Column 'EFFETTI.NUMFATT' is invalid in the select list because it is not
contained in either an aggregate function or the GROUP BY clause.
....."
.... per ognuno degli altri campi. Naturalmente lo stesso accade se aggiungo
la clausola "GROUP BY DATAEFF" o la clausola "GROUP BY DATAEFF, IDCLIENTE".
Insomma, non ho ben capito come si adopera l'istruzione GROUP BY e sarò
grato a chiunque mi voglia aiutare a scrivere la query funzionante.
--------------------------------
Inviato via 
http://arianna.libero.it/usenet/

 grato a chiunque mi voglia aiutare a scrivere la query funzionante.
Allora, semplificando il tutto:
- dopo la clausola SELECT hai n colonne;
- le colonne incluse nella selezione possono essere sostanzialmente di
due tipi, ovvero colonne che fanno riferimento a funzioni di
aggregazione (es. MAX) oppure no;
- dopo la clausola GROUP BY, devi includere tutte le colonne che *non*
fanno riferimento a funzioni di aggregazione.
Il tutto ha una logica, perché se chiedi a SQL Server di raggruppare i
dati, devi dirgli per quali colonne raggruppare. Ma se includi 10
colonne nella selezione e poi gli chiedi di raggruppare per 1 colonna,
come fa a sapere come deve trattare le 9 colonne restanti?!
Per maggiori dettagli, leggi i BOL.
-- 
David Martin


Ciao. Grazie per la risposta. Infatti è quella che avevo trovato anche io
sui BOL però non mi è chiaro per niente (sarà che sono di coccio!): ad
esempio: io non ho campi derivati da funzioni di aggregazione, quindi devo
specificare per forza tutti i campi nella clausola GROUP BY? Ma se è così,
che senso ha raggruppare solo per uno o due campi? O meglio, come si fa a
raggruppare solo per uno o due campi?
Inoltre, come tu dici giustamente, lui non sa come deve trattare i campi
restanti, ma non ho la possibilità di dirglielo io, cioè di dirgli una cosa
del tipo "... il campo XX non va raggruppato, il campo YY non va
raggruppato, ..."?
E poi mi sto chiedendo: ma è proprio di una clausola GROUP BY che ho
bisogno? Non c'è un altro modo per raggruppare i record in base a uno o due
campi? Adesso sto facendo dei tentativi con l'ORDER BY, ma anche grazie al
tuo intervento mi pare di capire che GROUP BY va usato quando ho bisogno di
fare somme, medie o conteggi in base a gruppi di record e io non ho bisogno
di queste operazioni, ma soltanto di tenere uniti tutti i record di un
determinato cliente, per poi passare ai record del cliente successivo, e
così via. Pensi che devo utilizzare GROUP BY, o magari mi serve
qualcos'altro?
Insomma sto cercando qualche dritta o qualche consiglio su come procedere
perché non sono sicuro di come andare avanti. Grazie ancora per la tua
attenzione.


 attenzione.
Ehm... più che non sapere come andare avanti, mi pare che non sia chiaro
cosa si vuole ottenere dai dati :-)  cerchiamo allora di capirlo...
Nel primo post dici che ti viene chiesta la possibilità di raggruppare:
- per cliente
- per data
- per cliente e per data
Domande:
1. Dov'è la colonna 'data' che nomini? Nelle colonne specificate dopo la
SELECT, non c'è alcuna colonna con quel nome
2. Che cosa ne facciamo delle colonne che non servono a raggruppare
([scadenza], [riferimento fattura], [banca cliente], [em.], [incass.],
[residuo], [insol.])?
Voglio dire, se raggruppo per cliente, mi posso trovare con n righe di
effetti. Che cosa vuole il tuo committente, avere il totale, la media,
l'elenco di tutti gli effetti?
-- 
David Martin

 l'elenco di tutti gli effetti?
Solo l'elenco, almeno per adesso. E se in seguito desiderasse totali o medie
penso di poterle ricavare agevolmente dai dati della griglia, senza bisogno
di ulteriori query con funzioni di aggregazione.
Vuole avere l'elenco degli effetti che scadono, diciamo, la settimana
prossima ma raggruppandoli per cliente. Cioè, tutti quelli del cliente
Tizio, poi tutti quelli del cliente Caio, poi tutti quelli del cliente
Sempronio, ...ecc. Oppure per data di scadenza: tutti quelli che scadono
lunedi, poi tutti quelli di martedi... Oppure per data e cliente. In
effetti, più mi sforzo di esporti il problema, più ho la sensazione che
posso farlo con un ORDER BY...
Spero che sia un po' più chiaro adesso, mi interessa molto sapere la tua
opinione.


 posso farlo con un ORDER BY...
...già, temo che sia proprio così.
Se nel linguaggio comune "raggruppare" può voler dire anche ordinare,
nel linguaggio sql non è proprio così, e quindi ci ha sviati sin
dall'inizio.
Quello che devi fare è un semplice ordinamento in base alle colonne
desiderate.
-- 
David Martin

 desiderate.
Infatti, dopo un po' di prove alla fine ho risolto facendo proprio in questo
modo, e riempiendo la grid con i valori ordinati questi appaiono
"raggruppati" insieme: tutti quelli di una certa data o di un certo cliente,
poi la data o il cliente successivo, e così via. E ho compreso anche lo
scopo dell'istruzione GROUP BY, che è quello di effettuare operazioni di
aggregazione. Lo terrò a mente per il futuro.
Ti ringrazio tantissimo per l'attenzione.
