Solved

How to pivot on multiple columns

Posted on 2012-03-16
9
420 Views
Last Modified: 2012-03-19
I am try to pivot the following data
Normalized data
USI   Review    Status
9        A             A
9        B             A
9        C             B
9        D            A
9        E             D
9        F             B
9        G             H
9        H             E

So that I get the following result
Pivoted Output
USI   Review1   Status1   Review2  Status2   Review3    Status3  
 9           A            A             B             A              C                B

I have written the following code

SELECT USI, [FRS] AS Review1, [Loss Mitigation Decisioning]AS Review2, [Loss Mitigation Handling] AS Review3
FROM
(SELECT USI, Review
    FROM dbo.vwAllReviewStatus
) AS SourceTable
PIVOT
(
max(Review)
FOR [Review] IN ([FRS], [Loss Mitigation Decisioning], [Loss Mitigation Handling])

) AS P1

Which gives me the following result
USI   Review1    Review2     Review3    
9          A                B                  C

I need some help in getting the status1, status2, and status3 fields in

Thanks
0
Comment
Question by:chtullu135
  • 5
  • 2
  • 2
9 Comments
 
LVL 42

Accepted Solution

by:
dqmq earned 400 total points
ID: 37731163
I think that in trying to simplify your question, the SQL you provided got mangled.

That said, try something like this:

declare @tab  table (USI int, Review char(1), status char(1))
insert @tab select 9, 'A', 'A'
insert @tab select 9, 'B', 'A'
insert @tab select 9, 'C', 'B'
insert @tab select 9, 'D', 'A'
insert @tab select 9, 'E', 'D'
insert @tab select 9, 'F', 'B'
insert @tab select 9, 'G', 'H'

Select USI
, max(r1) as Review1, max(s1) as Status1 
, max(r2) as Review2, max(s1) as Status2 
, max(r3) as Review3, max(s1) as Status3 
from
(
Select USI
, case when review='A' then review end as R1 
, case when review='A' then status end as S1 
, case when review='B' then review end as R2 
, case when review='B' then status end as S2 
, case when review='C' then review end as R3 
, case when review='C' then status end as S3 
from @tab
) as x 
group by usi

Open in new window

0
 

Author Comment

by:chtullu135
ID: 37731280
Hello dmg

I tried your code but the status stayed the same for all reviews
For the values of s1, s2, s3  I was expective A, A, B.  I got A ,A, A instead
0
 

Author Comment

by:chtullu135
ID: 37731346
Part of the problem was that

max(r1) as Review1, max(s1) as Status1
, max(r2) as Review2, max(s1) as Status2
, max(r3) as Review3, max(s1) as Status3

Should be
max(r1) as Review1, max(s1) as Status1
, max(r2) as Review2, max(s2) as Status2
, max(r3) as Review3, max(s3) as Status3
0
 
LVL 42

Expert Comment

by:dqmq
ID: 37731395
Good catch--copy/paste error on my part.  Let me know if there are other issues.
0
PRTG Network Monitor: Intuitive Network Monitoring

Network Monitoring is essential to ensure that computer systems and network devices are running. Use PRTG to monitor LANs, servers, websites, applications and devices, bandwidth, virtual environments, remote systems, IoT, and many more. PRTG is easy to set up & use.

 

Author Comment

by:chtullu135
ID: 37731936
Hello dqmq,
The code now works but I have some questions as to how it works.  In particular the following segment.  I understand the use of the Case when statement but not of "end as S1".  Could you clarify that for me.

Thanks

Select USI
, case when review='A' then review end as R1
, case when review='A' then status end as S1
, case when review='B' then review end as R2
, case when review='B' then status end as S2
, case when review='C' then review end as R3
, case when review='C' then status end as S3
0
 

Author Comment

by:chtullu135
ID: 37735518
I understand
"case when review='A' then review end as R1 "
but I am trying to figure out how
" case when review='A' then status end as S1 " is returning the correct status.  I don't really want to implement code without understanding how it works.
0
 
LVL 26

Expert Comment

by:Chris Luttrell
ID: 37736258
It will return the correct status if your values in the Review coulumn are distinct for any given USI value, i.e. only one each of A, B, C, D, E, F, G, H for USI=9.
0
 
LVL 26

Assisted Solution

by:Chris Luttrell
Chris Luttrell earned 100 total points
ID: 37736349
To do it with PIVOT like you were trying to do, try this:
SELECT USI,  MAX([Review1]) AS [Review1],  MAX([Status1]) AS [Status1],  MAX([Review2]) AS [Review2],  MAX([Status2]) AS [Status2],   MAX([Review3]) AS [Review3],  MAX([Status3]) AS [Status3],  MAX([Review4]) AS [Review4],  MAX([Status4]) AS [Status4],  MAX([Review5]) AS [Review5],  MAX([Status5]) AS [Status5],  MAX([Review6]) AS [Review6],  MAX([Status6]) AS [Status6],  MAX([Review7]) AS [Review7],  MAX([Status7]) AS [Status7]
FROM (
SELECT USI, Review, Status, 'Review'+CONVERT(VARCHAR(2),rn) ReviewPvtCol, 'Status'+CONVERT(VARCHAR(2),rn) StatusPvtCol
FROM (SELECT USI, Review, Status, ROW_NUMBER() OVER (PARTITION BY USI ORDER BY Review) rn FROM  dbo.vwAllReviewStatus) AS SourceTable
) p
PIVOT
(
max(Review) 
FOR ReviewPvtCol IN ([Review1], [Review2], [Review3], [Review4], [Review5], [Review6], [Review7])
) AS P1
PIVOT
(
max(Status) 
FOR StatusPvtCol IN ([Status1], [Status2], [Status3], [Status4], [Status5], [Status6], [Status7])
) AS P2
GROUP BY USI

Open in new window

You can PIVOT twice but each time consumes the colums used so I created 2 psudo columns ReviewPvtCol and StatusPvtCol and assigned them numbered values to keep Review1 lined up with Status1 and so on.
This way keeps you from having to code in the real values for A-H in the case statements tried above.  I only had your dummy data to go by, but see if it works or is close.  Here is the test code I ran
declare @tab  table (USI int, Review char(1), status char(1))
insert @tab select 9, 'A', 'A'
insert @tab select 9, 'B', 'A'
insert @tab select 9, 'C', 'B'
insert @tab select 9, 'D', 'A'
insert @tab select 9, 'E', 'D'
insert @tab select 9, 'F', 'B'
insert @tab select 9, 'G', 'H'
insert @tab select 19, 'B', 'A'
insert @tab select 19, 'C', 'B'
insert @tab select 19, 'A', 'C'
insert @tab select 19, 'D', 'A'
insert @tab select 19, 'G', 'H'
insert @tab select 19, 'E', 'D'
insert @tab select 19, 'F', 'B'

--Select USI
--, max(r1) as Review1, max(s1) as Status1 
--, max(r2) as Review2, max(s2) as Status2 
--, max(r3) as Review3, max(s3) as Status3 
--from
--(
--Select USI
--, case when review='A' then review end as R1 
--, case when review='A' then status end as S1 
--, case when review='B' then review end as R2 
--, case when review='B' then status end as S2 
--, case when review='C' then review end as R3 
--, case when review='C' then status end as S3 
--from @tab
--) as x 
--group by usi



SELECT USI,  MAX([Review1]) AS [Review1],  MAX([Status1]) AS [Status1],  MAX([Review2]) AS [Review2],  MAX([Status2]) AS [Status2],   MAX([Review3]) AS [Review3],  MAX([Status3]) AS [Status3],  MAX([Review4]) AS [Review4],  MAX([Status4]) AS [Status4],  MAX([Review5]) AS [Review5],  MAX([Status5]) AS [Status5],  MAX([Review6]) AS [Review6],  MAX([Status6]) AS [Status6],  MAX([Review7]) AS [Review7],  MAX([Status7]) AS [Status7]
FROM (
SELECT USI, Review, Status, 'Review'+CONVERT(VARCHAR(2),rn) ReviewPvtCol, 'Status'+CONVERT(VARCHAR(2),rn) StatusPvtCol
FROM (SELECT USI, Review, Status, ROW_NUMBER() OVER (PARTITION BY USI ORDER BY Review) rn FROM @tab) AS SourceTable
) p
PIVOT
(
max(Review) 
FOR ReviewPvtCol IN ([Review1], [Review2], [Review3], [Review4], [Review5], [Review6], [Review7])
) AS P1
PIVOT
(
max(Status) 
FOR StatusPvtCol IN ([Status1], [Status2], [Status3], [Status4], [Status5], [Status6], [Status7])
) AS P2
GROUP BY USI

Open in new window

to get this result
Results from Double Pivot
0
 

Author Closing Comment

by:chtullu135
ID: 37737876
I decided to split points.  Both solutions worked.  But after bench testing both solutions, I found that dqmq's solution executed much faster and so I chose that solution.  However, cgLutteral showed me how to pivot using multiple pivots which I found very informative.
0

Featured Post

Enterprise Mobility and BYOD For Dummies

Like “For Dummies” books, you can read this in whatever order you choose and learn about mobility and BYOD; and how to put a competitive mobile infrastructure in place. Developed for SMBs and large enterprises alike, you will find helpful use cases, planning, and implementation.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

How to leverage one TLS certificate to encrypt Microsoft SQL traffic and Remote Desktop Services, versus creating multiple tickets for the same server.
This article shows gives you an overview on SQL Server 2016 row level security. You will also get to know the usages of row-level-security and how it works
Via a live example, show how to extract insert data into a SQL Server database table using the Import/Export option and Bulk Insert.
Viewers will learn how to use the UPDATE and DELETE statements to change or remove existing data from their tables. Make a table: Update a specific column given a specific row using the UPDATE statement: Remove a set of values using the DELETE s…

867 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

16 Experts available now in Live!

Get 1:1 Help Now