Sunday, 14 April 2013

Sql server - Rows to table


Sql server - Rows to table...


Using pivot ans unpivot

You can use the PIVOT and UNPIVOT relational operators to manipulate a table-valued expression into another table. PIVOT rotates a table-valued expression by turning the unique values from one column in the expression into multiple columns in the output, and performs aggregations where necessary on any remaining column values that are desired in the final output. UNPIVOT performs the opposite operation to PIVOT by rotating columns of a table-valued expression into column values. Every PIVOT query involves an aggregation of some type.

There are two ways to pivot data:
  1.     We can convert multiple rows into a single row with repeating groups of columns.
  2.     We can convert columns on a single row into multiple rows with a generic column and a row type discriminator.

Use the following scripts,

CREATE TABLE Sales (State CHAR(2), SalesAmt DECIMAL(18,2))  

Insert values,

INSERT INTO Sales VALUES ('ND',10000)  
INSERT INTO Sales VALUES ('SD',30000)  
INSERT INTO Sales VALUES ('TN',2500.50)  
INSERT INTO Sales VALUES ('OR',5500.50)  
INSERT INTO Sales VALUES ('VA',6500.50)  
INSERT INTO Sales VALUES ('SD',7000)  
INSERT INTO Sales VALUES ('ND',8000)  
  SELECT * FROM Sales  

Here is the result set,


Run the following query,

SELECT [ND],[SD],[TN],[OR],[VA]  
FROM (SELECT State,SalesAmt FROM Sales) p  
PIVOT
(
SUM (SalesAmt)  
FOR State IN  
([ND],[SD],[TN],[OR],[VA])  
AS pvt  

Here is the result set,



UNPIVOT performs almost the reverse operation of PIVOT, by rotating columns into rows.
Use the following scripts,

Create the following table,  
CREATE TABLE StudentMarks(  
[NameVARCHAR(50),  
Subject1 VARCHAR(10),  
Mark1 INT,  
Subject2 VARCHAR(10),  
Mark2 INT,  
Subject3 VARCHAR(10),  
Mark3 INT)  

Insert some data into above table ans suppose select returns following result set,


Run the following query,

SELECT  [Name], SubjectName,  
case when Subject='Subject1' then Mark1  
     when Subject='Subject2' then Mark2  
     when Subject='Subject3' then Mark3  
    else NULL end as Marks  
FROM  
   (SELECT [Name], Subject1,Mark1, Subject2,Mark2, Subject3,Mark3  
   FROM StudentMarks) p  
UNPIVOT
   (SubjectName FOR Subject IN 
   (Subject1, Subject2, Subject3)
    )AS unpvt;  
Here is the result set,


Note that UNPIVOT is not the exact reverse of PIVOT. PIVOT performs an aggregation and hence merges possible multiple rows into a single row in the output. UNPIVOT does not reproduce the original table-valued expression result because rows have been merged. Besides, NULL values in the input of UNPIVOT disappear in the output, whereas there may have been original NULL values in the input before the PIVOT operation.