Home > SQL and .NET Blog > Multiple UNPIVOT in SQL Server

Multiple UNPIVOT in SQL Server

Learning multiple unpivot option was little interesting for me.

SELECT tempoid,version,dataField,datavalue,dataField1,datavalue1
 
FROM
 
      (SELECT t1.tempoid, t1.version, t1.data1, t1.data2, t1.data3, t1.data4, t2.data1 as d1, t2.data2 as d2, t2.data3 as d3, t2.data4 as d4
 
      FROM table1 t1 inner join table1 t2 on t1.tempoid = t1.tempoid and t1.version = t2.version + 1
 
      WHERE t1.version in (@version)
 
      ) AS p
 
UNPIVOT
 
      (datavalue FOR dataField IN
 
            (data1, data2, data3, data4)) as u1
 
 UNPIVOT (datavalue1 FOR dataField1 IN
 
      (d1, d2, d3, d4)) as u2

That’s it, simple

To under the above query, we will first create two tables and insert few records into

create table table1(OID BIGINT identity,tempoid bigint,version varchar(30),data1 varchar(30),data2 varchar(30),data3 varchar(30),data4 varchar(30))

create table table2(oid bigint identity,tempoid bigint,version varchar(30),fieldname varchar(30),Olddata varchar(30),Newdata varchar(30))

select * from table1

select * from table2

Let us first try inserting through this procedure

CREATE proc procInsert(@tempoid bigint,@version varchar(30),@data1 varchar(30),@data2 varchar(30),@data3 varchar(30),@data4 varchar(30))

AS

BEGIN

INSERT INTO table1 values(@tempoid,@version,@data1,@data2,@data3,@data4)

IF(@version >1)

BEGIN

;with cte as(

select tempoid,version,dataField,datavalue,dataField1,datavalue1

FROM

(SELECT t1.tempoid, t1.version, t1.data1, t1.data2, t1.data3, t1.data4, t2.data1 as d1, t2.data2 as d2, t2.data3 as d3, t2.data4 as d4

FROM table1 t1 inner join table1 t2 on t1.tempoid = t1.tempoid and t1.version = t2.version + 1

WHERE t1.version in (@version)

) AS p

UNPIVOT (datavalue FOR dataField IN (data1, data2, data3, data4)) as u1

UNPIVOT (datavalue1 FOR dataField1 IN (d1, d2, d3, d4)) as u2

)

–select * from cte

Insert into table2

select cte.tempoid,cte.version,cte.datafield,cte.datavalue1  as NewValue,cte.datavalue as OldValue

from cte inner join table1 t1 on t1.tempoid = cte.tempoid and t1.version = cte.version where ((cte.datafield = ‘data1’ and cte.datafield1 = ‘d1’)

or (cte.datafield = ‘data2’ and cte.datafield1 = ‘d2’) or (cte.datafield = ‘data3’ and cte.datafield1 = ‘d3’) or (cte.datafield = ‘data4’ and cte.datafield1 = ‘d4’))

AND cte.datavalue <> cte.datavalue1

END

END

go

procInsert 1,2,’2.1′,’2.2′,’2.3′,’2.4′

procInsert 1,3,’2.1′,’2.2′,’2.3′,’2.5′

Now select the records from both the tables

select * from table1

select * from table2

The required functionality is, the no of columns that are different from current row to its previous version

Those different columns should be recorded in a new table ‘table2’

now try inserting new row in table1 like

procInsert 1,4,’2.6′,’2.7′,’2.8′,’2.5′ — I have modified 3 columns here data1, data2 and data3

the result is :

(1 row(s) affected)

(3 row(s) affected)

and the output is

-Yuva

Categories: SQL and .NET Blog
  1. No comments yet.
  1. No trackbacks yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: