3.4.08

T-SQL Challenges - Part 1 -Pivot Operator

Problematic statement:
Consider two table 1 and 2 and they are linked by a common column "ID".
Table1 had the details about the person and table2 list down the scores availed by the person.
My problem is to combine these two table listing out the person and their marks in each subjects.
Assumptions:
In table2, the rows are added as per the subjects, first mark will be considered as subject1,
second mark will be considered as subject2,Thrid mark will be considered as subject3.
Below are the sample inputs and expected outputs,
SQLTable1:
Code Snippet

ID StudentName
1 Venkatesan
2 Arun
3 Santhi
4 Vijay

SQLTable2:
Code Snippet

ID Marks
1 90
1 20
1 80
2 78
2 67
3 89
3 65
3 98
4 78
4 76
4 45

Expected output from the above tables
Code Snippet

ID StudentName Sub1 Sub2 Sub3
---------------------------------------------------------

1 Venkatesan 90 20 80
2 Arun 78 67 NULL
3 Santhi 89 65 98
4 Vijay 78 76 45


Solution:
Microsoft sql server 2005 provides a very handy option of altering the rows to columns
using pivot property. To solve the above problem,
1. First we have to create a cte listing the rownumber partitioned by ID.
2. Pivot the data based on rownumber.
Code Snippet

--Creating table variables
declare @SQLTable1 table (id int,Studentname varchar(100))
declare @SQLTable2 table (id int,Marks int)
-- inserting the data into the table variables
insert into @SQLTable1
select '1','Venkatesan' union all
select '2','Arun' union all
select '3','Santhi' union all
select '4','Vijay'

insert into @SQLTable2
select '1','90' union all
select '1','20' union all
select '1','80' union all
select '2','78' union all
select '2','67' union all
select '3','89' union all
select '3','65' union all
select '3','98' union all
select '4','78' union all
select '4','76' union all
select '4','45'

--select * from @SQLTable1
--select * from @SQLTable2
--Creating rownumber in the cte
;with VenkatCTE as(

select a.id,a.Studentname, b.Marks,
row_number() over ( partition by a.id order by a.id) as rn
from @SQLTable1 a inner join @SQLTable2 b on a.id=b.id
)
--select * from VenkatCTE
-- pivoting the rows in the cte
select id,Studentname,[1] as Subject1,[2] as Subject2,[3] as Subject3
from VenkatCTE
pivot
(
min(Marks) for rn in ([1],[2],[3])
)
pvt
order by id

Happy learning!!!
Regards,
Venkatesan Prabu . J

4 comments:

  1. Hi Venketesan Prabhu..i am very much interested on your blog .like when ever i get a doubt on any thing related to sql server 2005 queries or any thing related i will first check ur blog....but just as my suggestion is to keep the output values screenshot also..so that it helps us a lot to knw...this is my suggestion..any how good works on sql and i want to know the extra features in sql server 2008..if u can post in ur blog it helps us a lot......

    ReplyDelete
  2. Sure,

    I have started providing the output screen.

    Thanks for your positive reply

    Venkatesan Prabu .J

    ReplyDelete
  3. Hi Venkat, i saw your Student sample query, I have a table where the colunmns are to be shown as columns
    The table structure is:
    ResId int, StatusId int, DateId int, HrId int, ResId int, price money

    Data looks like
    Row1: 546, 1, 8, 2, 5.00
    Row2: 546, 2, 6, 3, 6.00
    Row3: 546, 5, 7, 5, 12:00
    Row4: 566, 1, 4, 5, 6:00
    Row5: 566, 5, 6, 3, 4:00

    I need data like
    ResId StatusId1 DateId1 HrId1 price1 StatusId2 DateId2 HrId2 price2
    and so on

    546 1 8 2 5.00 2 6 3 6.00 5 7 5 12:00
    566 1 4 5 6:00 5 6 3 4:00

    The blanks are nulls
    Status is from 1 to 5 and is a look up dimension

    Any help is appreciated.

    Thanks

    Hema

    ReplyDelete
  4. The site SQL Reports has a great SQL tutorial. Highly rcommended for people just getting started on SQL selects.

    SQL Reports
    URL 1: http://wwwsql-reports.net/

    Sql tutorial
    URL 2: http://wwwsql-reports.net/2011/03/sql-select-tutorials.html

    regards
    glusce

    ReplyDelete