siquellando

...scoperte e considerazioni Sql di uno sviluppista
(un po' sviluppatore e un po' sistemista)

Feature "SAS like" in Sql2008

Buone news per i Sassisti in ascolto che lavorano in SqlServer: nella versione Sql2008 saranno presenti due funzionalita' che ricordano molto da vicino cio' che si ha (da illore tempo) a disposizione in SAS.

Mi riferisco allo statement MERGE che consente, in un singola operazione atomica, di effettuare Insert, Delete ed Update su una tabella target sulla base dei dati presenti in una tabella source.

E' qualcosa che consente facilmente in Sql di effettuare quelle operazioni di aggiornamento che si fanno in un data step SAS  con lo statement merge [stesso nome, appunto Smile] e l'opzione IN dei dataset.

Ecco un esempio di come aggiornare le informazioni presenti nella tabella Attivita sulla base di quelle presenti nella tabella UpdAttivita

/* setup test */
use tempdb
go


create table dbo.Attivita (Id int, Label varchar(20),Durata int);
go
create table dbo.UpdAttivita (Id int, Label varchar(20),Durata int);
go

insert into dbo.Attivita values (1,'Alfa',120),(2,'Beta',200),(3,'Gamma',80);

insert into dbo.UpdAttivita values (4,'Echo',10),(2,'Beta',210),(3,'GammaNew',801);


/* applico le variazioni */
merge into dbo.Attivita AS TGT
 using dbo.UpdAttivita AS SRC
 
 on TGT.id = SRC.id

when MATCHED then

  update set
    TGT.label = SRC.label,
    TGT.durata = SRC.durata

when NOT MATCHED then

  insert (id, label, durata)
  values (SRC.id, SRC.label, SRC.durata)

when SOURCE NOT MATCHED then
 delete
;

/* verifica */
select * from dbo.Attivita;

 Per i curiosi in SAS, in questo caso, bastava scrivere:

data Attivita;

merge Attivita (in=a) UpdAttivita(in=b);

by Id;

if a and not b then delete;

run;

 Che in effetti e' un po' piu' compatto Stick out tongue

 

L'altra funzionalita' introdotta e' quella dei GROUPING SETS che ci fanno ritrovare praticamente "pari pari" la Proc Summary all'interno di SqlServer.

Appoggiandosi a tale funzionalita' possiamo ottenere, con un unica query, piu' raggruppamenti, uno per ogni combinazione dei campi indicati nell'istruzione  Grouping Sets del Group By che diviene l'equivalente dell'istruzione CLASS della Proc Summary.

Ad esempio se volessimo, in un colpo solo, la somma delle vendite della tabella Vendite sia per IdProdotto che per PuntoVendita insieme alle somme per ogni combinazione di PuntoVendita e IdProdotto ed anche il Totalone con i Grouping Sets possiamo scrivere:

use tempdb
go

-- creazione tabella di esempio
if OBJECT_ID ('dbo.Vendite') is not null drop table dbo.Vendite;

create table dbo.Vendite (
 PuntoVendita varchar(20),
 IdProdotto  int,
 Quantita  int
 );
go

-- inserimento dati esempio
insert into dbo.Vendite (PuntoVendita,IdProdotto,Quantita)
Values
('Milano',1,120),
('Milano',2,124),
('Milano',3,210),
('Roma',1,300),
('Roma',2,155),
('Roma',3,38),
('Napoli',2,35)
;

/* calcolo i vari totali */


select  PuntoVendita, IdProdotto, SUM(Quantita) as Quantita
 from dbo.Vendite
 group by
 GROUPING Sets(
 (),
 (PuntoVendita ),
 (IdProdotto),
 (PuntoVendita,IdProdotto )
 )
 order by PuntoVendita , IdProdotto
 ;

Per gli interessati l'equivalente SAS sarebbe:

proc Summary data = Vendite print sum;

var Quantita;

class PuntoVendita  IdProdotto ;

run;

 

Mi piacciono, si mi piacciono veramente molto queste nuove possibilita' di Sql2008 Drinks


 

Posted: giu 26 2008, 01.58 by orsocurioso | with no comments
Filed under: ,