SQL Programmers Blog - Using PIVOT and UNPIVOT


  

Need help with Microsoft SQL Server? Ask our Experts, or simply Email your query.

About Sql Server Programmers

Our clients can be found both locally in the Chicagoland area and throughout the country. We have over 16 years of experience and are extremely proud of our track record of successfully assisting hundreds of our clients to improve their productivity while focusing on cost.

Microsoft Certified Partner

  

SQL Server Programmers Blog

Dec 23

Written by: host
12/23/2009 12:21 PM 

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,

PIVOT table results

Run the following query,

GO
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,

PIVOT table results

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

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

Insert values,

INSERT INTO StudentMarks([Name],Subject1,Mark1,Subject2,Mark2,Subject3,Mark3) 
VALUES('AAA','Science',98,'Maths',89,'English',76)
INSERT INTO StudentMarks([Name],Subject1,Mark1,Subject2,Mark2,Subject3,Mark3) 
VALUES('XXX','Biology',78,'Chemistry',85,'Physics',67)
INSERT INTO StudentMarks([Name],Subject1,Mark1,Subject2,Mark2) 
VALUES('YYY','Batany',60,'Zoology',54)
INSERT INTO StudentMarks([Name],Subject1,Mark1,Subject2,Mark2) 
VALUES('ZZZ','Maths',67,'Physics',78)

SELECT * FROM StudentMarks

Here is the result set,

PIVOT table results

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,

PIVOT table results

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.

Tags:

Your name:
Your email:
(Optional) Email used only to show Gravatar.
Your website:
Title:
Comment:
Security Code
Enter the code shown above in the box below
Add Comment   Cancel