Solved

How to pivot on multiple columns

Posted on 2012-03-16
9
424 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 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
Windows Server 2016: All you need to know

Learn about Hyper-V features that increase functionality and usability of Microsoft Windows Server 2016. Also, throughout this eBook, you’ll find some basic PowerShell examples that will help you leverage the scripts in your environments!

 
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
 

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

Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

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.
I have a large data set and a SSIS package. How can I load this file in multi threading?
Using examples as well as descriptions, and references to Books Online, show the documentation available for date manipulation functions and by using a select few of these functions, show how date based data can be manipulated with these functions.
This video shows how to set up a shell script to accept a positional parameter when called, pass that to a SQL script, accept the output from the statement back and then manipulate it in the Shell.

710 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