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
] 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 
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 