Newsgroup: it.comp.software.database
Titolo: Query di raggruppamento

Ho tre tabelle:
* responsabile,
* ufficio
* pratica
La tabella ufficio contiene id_responsabile.
La tabella pratica contiene id_ufficio.
La tabella pratica ha anche la data della pratica.
Dovrei avere un raggruppamento per responsabile con il count delle pratiche
divise per tipo di pratica (campo booleano true/false, aperta/chiusa) e che
infine soddisfino una certa data.
Io ne ho usata una del tipo:
SELECT responsabile.responsabile, COUNT(dbo.Pratica.conclusa) ,
dbo.Pratica.conclusa, dbo.responsabile.ID_responsabile
FROM dbo.ufficio INNER JOIN
                      dbo.Pratica ON dbo.ufficio.Id_ufficio = dbo.Pratica.id_ufficio RIGHT OUTER
JOIN
                      dbo.responsabile ON dbo.ufficio.ID_responsabile =
dbo.responsabile.ID_responsabile
GROUP BY dbo.ufficio.Id_ufficio, dbo.responsabile.responsabile,
dbo.Pratica.conclusa, dbo.responsabile.ID_responsabile, dbo.Pratica.Data
HAVING (CONVERT(varchar(10), dbo.Pratica.Data, 103) LIKE '%/%/%')
ORDER BY COUNT(dbo.Pratica.conclusa) DESC
Ma il campo data mi moltiplica i dati
	responsabile A 2 1 MNE
	responsabile A 1 1 MNE
	responsabile A 1 1 MNE
	responsabile A 1 1 MNE
	...omissis....
        responsabile A 1 0 MNE
	...omissis....
Invece che avere 
q.sa
 del tipo
       responsabile A 9 1 MNE
       responsabile A 5 1 MNE
Spero di essere stato chiaro... :))
Grazie per l'aiuto.
--------------------------------
Inviato via 
http://arianna.libero.it/usenet/

 ha scritto nel messaggio
news:62Z241Z2Z2Y10...@usenet.libero.it...

[CUT]
Ciao wonderfulworld
Togli la data da GROUP BY
--------------------------------------------
 SELECT responsabile.responsabile,
               COUNT(dbo.Pratica.conclusa) ,
              dbo.Pratica.conclusa,
              dbo.responsabile.ID_responsabile
 FROM dbo.ufficio
    INNER JOIN
                dbo.Pratica ON dbo.ufficio.Id_ufficio =
                dbo.Pratica.id_ufficio
   RIGHT OUTER  JOIN
                dbo.responsabile ON dbo.ufficio.ID_responsabile =
                dbo.responsabile.ID_responsabile
WHERE  (CONVERT(varchar(10), dbo.Pratica.Data, 103) LIKE '%/%/%')
GROUP BY dbo.responsabile.responsabile,
                    dbo.Pratica.conclusa,
                    dbo.responsabile.ID_responsabile
 ORDER BY COUNT(dbo.Pratica.conclusa) DESC
-----------------------------------------
Se poi vuoi avere su una riga le pratiche concluse e quelle non concluse
--------------------------------------------
 SELECT responsabile.responsabile,
               SUM(CASE WHEN dbo.Pratica.conclusa<>0 THEN 1 ELSE 0 END )
               AS Concluse,
               SUM(CASE WHEN dbo.Pratica.conclusa=0 THEN 1 ELSE 0 END )
               AS NonConcluse,
              dbo.responsabile.ID_responsabile
 FROM dbo.ufficio
    INNER JOIN
                dbo.Pratica ON dbo.ufficio.Id_ufficio =
                dbo.Pratica.id_ufficio
   RIGHT OUTER  JOIN
                dbo.responsabile ON dbo.ufficio.ID_responsabile =
                dbo.responsabile.ID_responsabile
WHERE  (CONVERT(varchar(10), dbo.Pratica.Data, 103) LIKE '%/%/%')
GROUP BY dbo.responsabile.responsabile,
                    dbo.responsabile.ID_responsabile
 ORDER BY Concluse DESC
-----------------------------------------
Ciao Giorgio


Ciao Giorgio,
grazie sei stato gentilissimo ed hai perfettamente centrato il problema (ed
io mi sono accorto quanto sono poco dimestico con le query...;-))).
Ti chiedo un ulteriore aiuto:
Sarebbe possibile estrarre tutti i responsabili anche quelli che non
rispondono alla clausola where(=> count delle pratiche =0)?
Grazie


 Grazie
Ciao wonderfulworld
vediamo...
--------------------------------------------
 SELECT responsabile.responsabile,
              COUNT(IsNull(Pra.conclusa,0)) ,
              IsNull(Pra.conclusa,0)  PraticaConclusa,
              responsabile.ID_responsabile
 FROM  responsabile
     LEFT JOIN
                Ufficio ON
Responsabile.Id_Responsabile=ufficio.ID_responsabile
     LEFT  JOIN
                (SELECT Id_Ufficio,Data,Conclusa
                 FROM    Pratica
                WHERE  (CONVERT(varchar(10), dbo.Pratica.Data, 103) LIKE
'%/%/%')) Pra
                ON Ufficio.Id_Ufficio=Pra.Id_Ufficio
GROUP BY responsabile.responsabile,
                    IsNull(Pra.conclusa,0),
                    responsabile.ID_responsabile
 ORDER BY COUNT(Pra.conclusa) DESC
-----------------------------------------
Se vuoi avere su una riga le pratiche concluse e quelle non concluse
--------------------------------------------
 SELECT responsabile.responsabile,
              COUNT(IsNull(Pra.conclusa,0)) ,
              SUM(CASE WHEN IsNull(Pra.conclusa,0)<>0 THEN 1 ELSE 0 END )
               AS Concluse,
               SUM(CASE WHEN IsNull(Pra.conclusa,0)=0 THEN 1 ELSE 0 END )
               AS NonConcluse,
              responsabile.ID_responsabile
 FROM  responsabile
     LEFT JOIN
                Ufficio ON
Responsabile.Id_Responsabile=ufficio.ID_responsabile
     LEFT  JOIN
                (SELECT Id_Ufficio,Data,Conclusa
                 FROM    Pratica
                WHERE  (CONVERT(varchar(10), Data, 103) LIKE '%/%/%')) Pra
                ON Ufficio.Id_Ufficio=Pra.Id_Ufficio
GROUP BY responsabile.responsabile,
                    responsabile.ID_responsabile
 ORDER BY Concluse DESC
-----------------------------------------
Cosě dovrebbe andare (la sintassi č giusta ma non avendo i dati non ho
potuto provarla)
Ciao Giorgio

 Ciao Giorgio
Grazie per la disponibilità e la solerzia.


 -----------------------------------------
 


 Grazie
Ciao Wonderfulworld
serve a creare una subTabella in cui vengono filtrati direttamente i record
in base alla data.
Prova questo esempio.
----------------------------------
use tempdb
go
--Creo la tabella clienti
Create table Clienti(
   Id_Cliente int,
   Nome varchar(20))
--Creo la tabella fatture
Create table Fatture (
   Numero int,
   data datetime,
   Totale numeric(18,2),
   Id_Cliente int)
--Inserisco alcuni clienti
Insert clienti values(1,'Cliente 1')
Insert clienti values(2,'Cliente 2')
Insert clienti values(3,'Cliente 3')
--Inserisco alcune fatture per i clienti 1 e 2
Insert Fatture Values(1,'20031215',1000,1)
Insert Fatture Values(2,'20031216',2000,2)
Insert Fatture Values(3,'20031217',3000,1)
--Prima query rende solo il cliente 1 e 2
-------------------------------------------
SELECT C.Nome,
       C.Id_Cliente,
       SUM(IsNull(F.Totale,0)) AS Fatturato
FROM   Clienti C
  LEFT JOIN
       Fatture F ON C.Id_Cliente=F.Id_Cliente
WHERE Data Between '20031201' AND '20031231'
GROUP BY C.Nome,
         C.Id_Cliente
------------------------------------------
--Risultato
--Nome         Id_Cliente  Fatturato
-------------- ----------- ---------
--Cliente 1              1   4000.00
--Cliente 2              2   2000.00
--Seconda query rende anche il cliente 3 con totale a 0
------------------------------------------
SELECT C.Nome,
       C.Id_Cliente,
       SUM(IsNull(F.Totale,0)) AS Fatturato
FROM   Clienti C
  LEFT JOIN
       (SELECT Id_Cliente,Totale
        FROM Fatture
        WHERE Data Between '20031201' AND '20031231'
        ) F ON C.Id_Cliente=F.Id_Cliente
GROUP BY C.Nome,
         C.Id_Cliente
------------------------------------------
--Risultato
--Nome         Id_Cliente  Fatturato
-------------- ----------- ---------
--Cliente 1              1   4000.00
--Cliente 2              2   2000.00
--Cliente 3              3       .00
--In altro caso devi includere le date a NULL
-------------------------------------------
SELECT C.Nome,
       C.Id_Cliente,
       SUM(IsNull(F.Totale,0)) AS Fatturato
FROM   Clienti C
  LEFT JOIN
       Fatture F ON C.Id_Cliente=F.Id_Cliente
WHERE Data Between '20031201' AND '20031231'
   OR Data Is Null --<------
GROUP BY C.Nome,
         C.Id_Cliente
------------------------------------------
--Risultato
--Nome         Id_Cliente  Fatturato
-------------- ----------- ---------
--Cliente 1              1   4000.00
--Cliente 2              2   2000.00
--Cliente 3              3       .00
--Pulizia
Drop table Clienti,Fatture
------------------------------------------
Ciao Giorgio