Hello, I’m briefly going to discuss one topic that can easily throw you under the bridge if you did not take the time to actually practice it. Pivot and unpivot is not your regular every day TSQL term but its good to know it and use it when needed. We are going to take baby steps here to understand it from the very basic.

In SQL, a pivot table is a set of data that is transformed from a collection of separate rows to a collection of columns.
Pivot tables can be used to simplify extensive data in order to make it easier to read and understand. Lets take a look at a salestable

saleid product    customer salesdate    amount
1 laptop    cosby 2008    100
2 camera    kofi 2009    90
3 phone    cosby 2008    80
4 ipad    vince 2010    60

In a regular SQL, you find total sales to each customer each year like this

SELECT customer, salesdate, Sum(amount)

FROM salestable

GROUP BY salesdate, customer

that will give you the result below

customer    salesdate        amount

cosby          2008           $180

kofi                2009           $ 90

Vince            2011            $ 60

Now, what about if l want a result like below

customer     laptop              camera     phone     Ipad

cosby             $80                  $20           $60          $ 30

kofi                $ 70                  $10            $40          $5

This result displays each item l have in the store at the top, then in each record, it shows how much a customer spent in total on each item in my store.  Lets say this customer buys all these items on daily basis.  For example, a production company selling to retailers.

what about if l want a result like below also

customer         2008         2009       2010

cosby                 $180         $200        $300

vince                  $40            $90          $500

This result shows each customer and how much they spent in my store each year. This are different views of the same table and this result actually looks easier to comprehend, this is the idea of the pivot table.

To create a pivot table, an aggregate is used against a set of data to distribute multiple rows of a single column into a single row with multiple columns. This essentially pivots the result set sideways. This is very good especially for reporting purposes because it makes it easy for people to compare what is going on their business.

Lets see how we can achieve the first result using TSQL.

SELECT Customer, Laptop, Camera, Phone, Ipad
FROM(
SELECT Customer,Product,Amount
FROM salestable) a
PIVOT(
SUM(Amount)
FOR Product  in ( Laptop, Camera, Phone, Ipad)
) b

What is going on here?

Easy money, in the first statement we select the headers we want for the result from a derived table that gave us the customer, product and amount. It is recommend to name the derived table. I hope you understand a derived table, it’s simple a select statement that is given an alias name and can now act as a table for all kinds of TSQL table operations. If you have any doubt about derived table, please search for it right here on the blog, there is tutorial on it. Ok, so after we select the columns we want for our headers, we use the keyword PIVOT and put into bracket our aggregation function and the keyword FOR, which first specify the column in the derived table whose rows of record are now distributed into multiple columns. Then comes the IN operator which is use for searching in a list of items and a bracket containing all the columns we created using the single column from the original table, and this entire pivot statement is also give an alias b. This definition is rather long but l hope you understand the meat of the whole game.

Lets see how we can accomplish the second result

SELECT customer,[2008],[2009],[2010]
FROM(
SELECT customer,salesdate,amount
FROM salestable) a
PIVOT(
SUM(amount)
FOR salesdate in ([2008],[2009],[2010])
) b

The same logic applies here. so to make things very simple for us, let’s come up with a syntax that will help us on daily basis

SELECT <columns to show in the pivot table>

FROM( SELECT <columns> FROM <table>   ) AS  ‘derived table’

PIVOT(   Aggregate function(<column in derived table to aggregate>)

FOR   <column in derived table to group by> IN (<columns in header of result created from a single column in derived table>)

) As ‘Pivot derived table’

ORDER BY <pivot derived table>.<column> —optional step for ordering the records.

Try this at home, its good when you practice it. Here is the complete code, you can copy and paste in Microsoft SQL Server Management Studio and execute to see the results.

–Create a table

CREATE TABLE salestable(salesid int identity, product nvarchar(100) not null,customer nvarchar(100) not null ,salesdate date, amount money not null)

GO

–Put some records into the table

INSERT INTO salestable(product, customer, salesdate, amount)
values

(‘Laptop’,’Bush’,’2008-4-10′,100),
(‘Camera’,’Clinton’,’2009-2-1′,90),
(‘Phone’,’Obama’,’2008-1-1′,80),
(‘Ipad’,’Atta’,’2010-9-1′,60),

(‘Camera’,’Bush’,’2008-4-10′,100),
(‘Laptop’,’Clinton’,’2009-2-1′,90),
(‘Phone’,’Obama’,’2008-1-1′,80),
(‘Camera’,’Atta’,’2010-9-1′,60),

(‘Ipad’,’Bush’,’2008-4-10′,100),
(‘Phone’,’Clinton’,’2009-2-1′,90),
(‘Ipad’,’Obama’,’2008-1-1′,80),
(‘Phone’,’Atta’,’2010-9-1′,60),

(‘Phone’,’Bush’,’2008-4-10′,100),
(‘Ipad’,’Clinton’,’2009-2-1′,90),
(‘Laptop’,’Obama’,’2008-1-1′,80),
(‘Laptop’,’Atta’,’2010-9-1′,60)

— Query to see customers and total sales made each year

SELECT customer, YEAR(salesdate) AS ‘Year’, Sum(amount)

FROM salestable

GROUP BY YEAR(salesdate), customer

–Pivot table sample 1

SELECT customer,laptop,camera,phone,Ipad
FROM(
SELECT customer,product,amount
FROM salestable) a
PIVOT(
SUM(amount)
FOR product in (laptop,camera,phone,Ipad)
) b

–Pivot table sample 2

SELECT customer,[2008],[2009],[2010]
FROM(
SELECT customer,YEAR(salesdate),amount
FROM salestable) a
PIVOT(
SUM(amount)
FOR YEAR(salesdate) in ([2008],[2009],[2010])
) b

Now our next friend is Unpivot. This is basically the reverse of the pivot table, that means, assume we have stored the result set we generated using our examples above in a database and now, we are interested in generating the original table out of the pivoted table.

I always feel this is more complex than generating the pivot table because, in pivot table, we have the details and we simply aggregate to get the result the way we want it. But all the same, we have to know how to do this unpivot thing too. Before we go into this, there is a trick part to this, the unpivot is not going to get the exact table back as the original because when we perform the pivot operation, there is aggregation and merge going on and it’s not possible to retrieve every detail back. So let’s try this,

Now lets assume we store the result set we generated in the first case in the database in a table called pivotedtable, l’m talking about the one below.

customer     laptop              camera     phone     Ipad

cosby             80                   20            60            30

kofi                 70                   10             40           5

Now, how can we unpivot this result so that we go back to the original like below

Customer    Product     Salesdate                 Amount

Cosby            Laptop       2008-1-11              10

Cosby            Laptop      2008-2-10                70

Cosby           camera     2011-2- 11                60

I hope you can see the problem we are facing here. how do we get the details of everything? This is why l said earlier unpivot will not give us exactly the original table but it will try to give us as much as it can. The syntax for both pivot and unpivot are very similar.

Let’s try to unpivot the result and explain what is going on. Since we don’t have any date information, we’ll leave out the salesdate.

SELECT customer, Product,Amount
FROM(SELECT Customer, Laptop, Camera, Phone, Ipad
FROM pivotedtable ) pvt
UNPIVOT(Amount FOR Product IN (Laptop, Camera, Phone, Ipad )
) unpvt

we can see  the syntax is almost the same.  first, we select columns to see from a derived table that does not actually contain all of them. unpivot it to get the rest of the columns we are selecting in the header using Amount and FOR keyword on our Product Column to specify which columns in the derived table we are interested in getting information from.

Practice it at home. if you want to create the pivottedtable l’m using above, just do it like this

SELECT customer,laptop,camera,phone,Ipad
INTO pivottedtable
FROM(
SELECT customer,product,amount
FROM salestable) a
PIVOT(
SUM(amount)
FOR product in (laptop,camera,phone,Ipad)
) b

Selecting into will create the table for you and store the result in it on the fly. after that, write the unpivot query to see the result.

In the next tutorials, l’ll be doing lot of work on differences between different database objects. Advantages and disadvantages and limitations. All corrections, questions and feedback welcome. Stay blessed. Peace.

 

1 thought on “TSQL Tutorial 26: Pivot and Unpivot

Leave a Reply

Your email address will not be published. Required fields are marked *

Name *