Somma di un campo e raggrupparlo

venerdì 17 aprile 2009 - 16.19

sanfra Profilo | Junior Member

Somma dei campi con raggruppamento Salve, ho bisogno ancora del Vostro aiuto per una query e spero mi possiate ancora dare il vsotro appoggio.

Ho una tabella che chiamo Utente che ha 3 campi CF char(16) not null pk,Mese char(6) NOT NULL PK,GRUPPO char(7) NOT NULL PK

così riempita
sanfra1976 - 092008 - 0001
sanfra1976 - 102008 - 0002
sanfra1976 - 112008 - 0003

poi ho un altra tabella che chiamo utentebis che ha gli stessi campi della tabella sopra ma con dati differenti ma con i gruppi uguali a quelli della tabella Utente

quindi:

pippo - 092008 - 0001
pluto - 102008 - 0002


poi abbiamo una tabella che chiamo assenze che è così composta CF char(16) not null pk, mese chat(6) not null pk, assenze decimal(6,2) null

ed avrà tutti gli utenti in un preciso mese con le assenze fatte in quel mese

pippo - 092008 - 3,4
pluto - 102008 - 4,4

adesso, dopo aver spiegato la situazione delle tabelle e spero bene,
io devo prendere tutti gli utenti(utentebis) che sono associati all'utente(Utente) e fare la somma delle ore di assenza

Spero che anche in quest'ultimo caso sia stato chiaro

Grazie

lbenaglia Profilo | Guru

>adesso, dopo aver spiegato la situazione delle tabelle e spero
>bene,
Per spiegarti ancora meglio posta un esempio completo con la struttura delle tabelle (CREATE TABLE), alcune righe di prova (INSERT INTO) ed il result set finale che vorresti ottenere con quei dati.

>io devo prendere tutti gli utenti(utentebis) che sono associati
>all'utente(Utente) e fare la somma delle ore di assenza
>
>Spero che anche in quest'ultimo caso sia stato chiaro
Coi dati che hai postato non otterrai alcuna riga dato che pippo e pluto non sono presenti nella prima tabella.

>Grazie
Prego.

Ciao!
--
Lorenzo Benaglia
Microsoft MVP - SQL Server
http://blogs.dotnethell.it/lorenzo/
http://italy.mvps.org

sanfra Profilo | Junior Member

Allora innanzitutto grazie per il tuo intervento.

Le tabelle sono queste:

CREATE TABLE SV_MERITO(SV char(16) NOT NULL PRIMARY KEY,Mese char(6) NOT NULL Primary key,GRUPPO char(6) NOT NULL PRIMARY KEY)

SV è l'equivalente del codicefiscale che per motivi di privacy non potrò inserire.
INSERT INTO SV_MERITO(SV,Mese,GRUPPO)VALUES('TIZIO','092008','GRP001');
INSERT INTO SV_MERITO(SV,Mese,GRUPPO)VALUES('TIZIO','102008','GRP002');
INSERT INTO SV_MERITO(SV,Mese,GRUPPO)VALUES('Pluto','092008','GRP003');
INSERT INTO SV_MERITO(SV,Mese,GRUPPO)VALUES('Pluto','102008','GRP004');


CREATE TABLE UT_MERITO(UT char(16) NOT NULL PRIMARY KEY,Mese char(6) NOT NULL PRIMARY KEY,GRUPPO char(6) NOT NULL PRIMARY KEY)

INSERT INTO SV_MERITO(SV,Mese,GRUPPO)VALUES('PIPPO','092008','GRP001');
INSERT INTO SV_MERITO(SV,Mese,GRUPPO)VALUES('PIPPO','102008','GRP002');
INSERT INTO SV_MERITO(SV,Mese,GRUPPO)VALUES('sanfra1976','092008','GRP003');
INSERT INTO SV_MERITO(SV,Mese,GRUPPO)VALUES('sanfra1976','102008','GRP004');



CREATE TABLE GIORN_MESE(CF char(16) NOT NULL PRIMARY KEY,Mese char(6) NOT NULL PRIMARY KEY,ASSENTEISMO INT NULL )

INSERT INTO SV_MERITO(CF,Mese,ASSENTEISMO)VALUES('PIPPO','092008',5);
INSERT INTO SV_MERITO(SV,Mese,ASSENTEISMO)VALUES('PIPPO','102008',3,9);
INSERT INTO SV_MERITO(SV,Mese,ASSENTEISMO)VALUES('sanfra1976','092008',10);
INSERT INTO SV_MERITO(SV,Mese,ASSENTEISMO)VALUES('sanfra1976','102008',20);


Queste sono le tabelle interessate a farmi tornare il seguente risultato

TIZIO la somma dell'assenteismo che ha lo stesso gruppo nella tabella UT_MERITO / count(*)

quindi TIZIO = 8,9/2


Spero di essere stato chiaro

Grazie ancora per il tuo aiuto

lbenaglia Profilo | Guru

>Spero di essere stato chiaro
Mi spiace ma non ho capito niente
Ma hai provato ad eseguire il codice che hai postato?

Ciao!
--
Lorenzo Benaglia
Microsoft MVP - SQL Server
http://blogs.dotnethell.it/lorenzo/
http://italy.mvps.org

sanfra Profilo | Junior Member

>Mi spiace ma non ho capito niente
>Ma hai provato ad eseguire il codice che hai postato?


Certo che ho eseguito il codice e funziona perfettamente, l'unica cosa che facendo copia e incolla ho sbagliato nella insert dell'ultima tabella che ho lasciato i SV al posto dei cf,ma per il resto funziona tutto.

Se mi dici cosa di preciso non ti è chiaro possiamo anche trovare una soluzione.

Grazie

lbenaglia Profilo | Guru

>Certo che ho eseguito il codice e funziona perfettamente
Funziona perfettamente?
Il codice sorgente non è stato renderizzato qui
perchè non c'è sufficiente spazio.
Clicca qui per visualizzarlo in una nuova finestra
E mi fermo qua.

>l'unica cosa che facendo copia e incolla ho sbagliato nella insert dell'ultima
>tabella che ho lasciato i SV al posto dei cf,ma per il resto
>funziona tutto.
Come vedi non è "l'unica cosa" che non va.

>Se mi dici cosa di preciso non ti è chiaro possiamo anche trovare
>una soluzione.
Mi sembra di essere stato chiaro: posta un esempio completo FUNZIONANTE con la struttura delle tabelle (CREATE TABLE), alcune righe di prova (INSERT INTO) ed il result set finale che vorresti ottenere con quei dati.

>Grazie
Prego.

Ciao!
--
Lorenzo Benaglia
Microsoft MVP - SQL Server
http://blogs.dotnethell.it/lorenzo/
http://italy.mvps.org

sanfra Profilo | Junior Member

IL punto è che io ho solo il Diagramma delle tabelle in sql server 2000, oltretutto è un progetto che mi hanno assegnato fatto da qualcun'altro e che io sto modificando sia lato sql che lato codice.

Il create table non c'è l'ho oppure se mi dici come faccio a trovarlo avendo solo il diagramma dell'sql, io ho preso il nome delle tabelle e ho provato a simulare la creazione delle tabelle che poi in realtà sono quasi simili così come le ho postate.



Comunque grazie lo stesso per l'aiuto, alla prossima

lbenaglia Profilo | Guru

>IL punto è che io ho solo il Diagramma delle tabelle in sql server
>2000, oltretutto è un progetto che mi hanno assegnato fatto da
>qualcun'altro e che io sto modificando sia lato sql che lato
>codice.
Se hai il diagramma hai anche il db che le contiene.

>Il create table non c'è l'ho oppure se mi dici come faccio a
>trovarlo avendo solo il diagramma dell'sql, io ho preso il nome
>delle tabelle e ho provato a simulare la creazione delle tabelle
>che poi in realtà sono quasi simili così come le ho postate.
Per generare lo script della tabella, selezionala da Enterprise Manager, tasto DX, All Tasks, generate SQL Script..., avendo cura di selezionare nel tab Options la check box "Script PRIMARY keys, FOREIGN keys, defaults, and check constraints".
I comandi di INSERT con i dati di esempio li puoi creare a manina in 5 minuti.

>Comunque grazie lo stesso per l'aiuto, alla prossima
Prego.

Ciao!
--
Lorenzo Benaglia
Microsoft MVP - SQL Server
http://blogs.dotnethell.it/lorenzo/
http://italy.mvps.org

sanfra Profilo | Junior Member

Grazie non conoscevo questa prassi, incredibile come si imparino nuove cose puntando su altro..

questa è la tabella GIORN_MESE
CREATE TABLE [dbo].[GIORN_MESE] (
[CF_OP] [char] (16) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL ,
[MESE] [char] (7) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL ,
[ORE_ASSENZA] [decimal](6, 2) NULL ,
[ASSENTEISMO] [decimal](6, 3) NULL ,
[ORE_TOT] [decimal](6, 2) NULL
) ON [PRIMARY]

questa è la tabella SV_MERITO
CREATE TABLE [dbo].[SV_Merito] (
[SV] [char] (16) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL ,
[Mese] [char] (7) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL ,
[ID_Gruppo] [char] (7) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL ,
[ResaMedia] [decimal](6, 2) NULL ,
[SlaMedio] [decimal](9, 2) NULL ,
[Ko_qualita] [bit] NULL ) ON [PRIMARY]


questa è la tabella UT_Merito

CREATE TABLE [dbo].[UT_MERITO] (
[OP] [char] (16) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL ,
[Mese] [char] (7) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL ,
[ID_GRUPPO] [char] (7) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL,

) ON [PRIMARY]

La INSERT Nella Tabella UT_MERITO
PIPPO 012009 GRP0126
PIPPO 022009 GRP0135
PIPPO 092008 GRP0016


LA INSERT nella Tabella GIORN_MESE

PIPPO 012009 22,5 0,273 82,5
PIPPO 022009 40 0,5 80
PIPPO 092008 3,5 0,04 87

LA INSERT Nella Tabella SV_MERITO

sanfra1976 012009 GRP0126 0,6 0 0
sanfra1976 022009 GRP0135 0,45 0 0
sanfra1976 092008 GRP0016 0,06 0 0


quello che si nota e che penso aver già detto nei precedenti post è che nella SV_MERITO abbiamo un Superiore e nella tabella UT_MERITO abbiamo chi sta sotto di lui e nella Tabella GIORN_MESE abbiamo le assenze che ha fatto il dipendete che sta sotto un superiore, ma il superiore ha molti dipendenti che si allacciano a lui tramite un GRUPPO
adesso io voglio sapere Per quel Superiore,in quel mese, la somma dell'assenteismo dei sui dipendenti che poi questa somma va anche divisa per il numero di dipendenti che fanno parte in quel mese, per quel superiore.

Speriamo che questa volta sia quella buona

e grazie ancora della tua pazienza e aiuto

Fammi sapere se hai bisogno di altro

lbenaglia Profilo | Guru

>Speriamo che questa volta sia quella buona
Per semplificarti il discorso ho riscritto i comandi di CREATE TABLE e di INSERT:

USE tempdb; CREATE TABLE dbo.GIORN_MESE ( CF_OP char(16) NOT NULL , MESE char(7) NOT NULL , ORE_ASSENZA decimal(6, 2) NULL , ASSENTEISMO decimal(6, 3) NULL , ORE_TOT decimal(6, 2) NULL ); CREATE TABLE dbo.SV_MERITO ( SV char(16) NOT NULL , Mese char(7) NOT NULL , ID_Gruppo char (7) NOT NULL , ResaMedia decimal(6, 2) NULL , SlaMedio decimal(9, 2) NULL , Ko_qualita bit NULL ); CREATE TABLE dbo.UT_MERITO ( OP char(16) NOT NULL , Mese char(7) NOT NULL , ID_GRUPPO char(7) NOT NULL, ); INSERT dbo.GIORN_MESE VALUES ('PIPPO', '012009', 22.5, 0.273, 82.5) , ('PIPPO', '022009', 40, 0.5, 80) , ('PIPPO', '092008', 3.5, 0.04, 87); INSERT dbo.SV_MERITO VALUES ('sanfra1976', '012009', 'GRP0126', 0.6, 0, 0) , ('sanfra1976', '022009', 'GRP0135', 0.45, 0, 0) , ('sanfra1976', '092008', 'GRP0016', 0.06, 0, 0); INSERT dbo.UT_MERITO VALUES ('PIPPO', '012009', 'GRP0126') , ('PIPPO', '022009', 'GRP0135') , ('PIPPO', '092008', 'GRP0016');

> adesso io voglio sapere Per quel Superiore,in quel mese, la somma dell'assenteismo dei sui dipendenti che poi questa somma va anche divisa per il numero di dipendenti che fanno parte in quel mese, per quel superiore.
Traduci in un result set quello che hai scritto, basandoti sui comandi di INSERT postati.

Ciao!
--
Lorenzo Benaglia
Microsoft MVP - SQL Server
http://blogs.dotnethell.it/lorenzo/
http://italy.mvps.org

sanfra Profilo | Junior Member

>Traduci in un result set quello che hai scritto, basandoti sui
>comandi di INSERT postati.

che vuol dire?

IO avevo giò iniziato a scrivere qualche riga di codice ed è venuto fuori questo
select sv.SV,ut.OP,(sum(gm.Assenteismo)/count(*)) as assenze,gm.Mese from ut_merito ut join sv_merito sv on ut.OP <> sv.SV join giorn_mese gm on gm.CF_OP = ut.OP and gm.mese = ut.Mese where ut.OP = gm.CF_OP and ut.Mese = gm.Mese group by sv.SV,gm.Assenteismo,gm.mese,ut.OP order by sv.SV,gm.Mese,ut.OP

quello che viene fuori sono tutte le righe , ma non riesco a raggrupparle per mese e per sv

inoltre vedrai la parte
ut.OP <> sv.SV
e sta a sigificare che nella tabella ut ci possono essere anche i superiori, ma per altresituazioni.

Non so era questo quello che volevi?

Grazie


lbenaglia Profilo | Guru

>>Traduci in un result set quello che hai scritto, basandoti sui
>>comandi di INSERT postati.
>
>che vuol dire?

col1 col2 col n ----- ----- ... ----- val1 val2 ... val n val3 val4 ... val x ...

--
Lorenzo Benaglia
Microsoft MVP - SQL Server
http://blogs.dotnethell.it/lorenzo/
http://italy.mvps.org

sanfra Profilo | Junior Member

Si, scusa se non avevo intuito al volo la tua giustissima richiesta.

allora io vorrei

SV Mese assenteismo
---- -------- ---------------
sanfra1976 092008 3.5


il fatto è che gli insert che ti ho dato si rifanno a solo un utente oppure ad un mese oppure ancora ad un superiore mentre nella realtà nel db ci sono più mesi con più utenti nello stesso mese che hanno assenze e ed per questo che poi mi si chiede la somma dell'assenteismo degli utenti in quel mese sotto quel superiore, con la relativa media.

sanfra Profilo | Junior Member

NOn sono stato acnora una volta chiaro?
Anche perchè non riesco ancora a venirne ad una conclusione

lbenaglia Profilo | Guru

>allora io vorrei
>
>SV Mese assenteismo
>---- -------- ---------------
>sanfra1976 092008 3.5


Boh, con i dati che hai postato io ottengo un risultato ben diverso:

USE tempdb; CREATE TABLE dbo.GIORN_MESE ( CF_OP char(16) NOT NULL , MESE char(7) NOT NULL , ORE_ASSENZA decimal(6, 2) NULL , ASSENTEISMO decimal(6, 3) NULL , ORE_TOT decimal(6, 2) NULL ); CREATE TABLE dbo.SV_MERITO ( SV char(16) NOT NULL , Mese char(7) NOT NULL , ID_Gruppo char (7) NOT NULL , ResaMedia decimal(6, 2) NULL , SlaMedio decimal(9, 2) NULL , Ko_qualita bit NULL ); CREATE TABLE dbo.UT_MERITO ( OP char(16) NOT NULL , Mese char(7) NOT NULL , ID_GRUPPO char(7) NOT NULL, ); INSERT dbo.GIORN_MESE VALUES ('PIPPO', '012009', 22.5, 0.273, 82.5) , ('PIPPO', '022009', 40, 0.5, 80) , ('PIPPO', '092008', 3.5, 0.04, 87); INSERT dbo.SV_MERITO VALUES ('sanfra1976', '012009', 'GRP0126', 0.6, 0, 0) , ('sanfra1976', '022009', 'GRP0135', 0.45, 0, 0) , ('sanfra1976', '092008', 'GRP0016', 0.06, 0, 0); INSERT dbo.UT_MERITO VALUES ('PIPPO', '012009', 'GRP0126') , ('PIPPO', '022009', 'GRP0135') , ('PIPPO', '092008', 'GRP0016'); SELECT SV.SV, SV.Mese, SUM(GM.ASSENTEISMO) / COUNT(*) AS Assenteismo FROM dbo.SV_MERITO AS SV JOIN dbo.UT_MERITO AS UT ON SV.ID_Gruppo = UT.ID_GRUPPO AND SV.Mese = UT.Mese JOIN dbo.GIORN_MESE AS GM ON UT.OP = GM.CF_OP AND UT.Mese = GM.MESE GROUP BY SV.SV, SV.Mese; /* Output: SV Mese Assenteismo ---------------- ------- ------------ sanfra1976 012009 0.273000 sanfra1976 022009 0.500000 sanfra1976 092008 0.040000 (3 row(s) affected) */ DROP TABLE dbo.GIORN_MESE, dbo.SV_MERITO, dbo.UT_MERITO;


--
Lorenzo Benaglia
Microsoft MVP - SQL Server
http://blogs.dotnethell.it/lorenzo/
http://italy.mvps.org

sanfra Profilo | Junior Member

Innanzitutto ancora grazie per la tua disponibilità e di non avermi abbandonato, adesso ci sbatterò la testa per confrontare i risultati e ti farò sapere se è tutto ok, anche se ad occhio mi sembra funzionante.

sanfra Profilo | Junior Member

Allora, io pensavo si trattasse di una select, mentre mi èstato confermato che dovrei fare un update su un campo aggiunto nella tabella UT.MERITO

CREATE TABLE dbo.UT_MERITO (
OP char(16) NOT NULL ,
Mese char(7) NOT NULL ,
ID_GRUPPO char(7) NOT NULL,
Punti INT NULL
);

ho provato a trasformare la tua select in update in questo modo:

update ut_merito dbo.UT_MERITO AS UT SET punti =( select 15 FROM dbo.SV_MERITO AS SV JOIN dbo.UT_MERITO AS UT ON SV.ID_Gruppo = UT.ID_GRUPPO AND SV.Mese = UT.Mese JOIN dbo.GIORN_MESE AS GM ON UT.OP = GM.CF_OP AND UT.Mese = GM.MESE GROUP BY SV.SV, SV.Mese having (SUM(GM.ASSENTEISMO) / COUNT(*)) <0.04)
ma mi dà il seguente errore:
Subquery returned more than 1 value. This is not permitted when the subquery follows =, !=, <, <= , >, >= or when the subquery is used as an expression.
The statement has been terminated.

sanfra Profilo | Junior Member

Nessun altro piccolo suggerimento?

Partecipa anche tu! Registrati!
Hai bisogno di aiuto ?
Perchè non ti registri subito?

Dopo esserti registrato potrai chiedere
aiuto sul nostro Forum oppure aiutare gli altri

Consulta le Stanze disponibili.

Registrati ora !
Copyright © dotNetHell.it 2002-2023
Running on Windows Server 2008 R2 Standard, SQL Server 2012 & ASP.NET 3.5