Solved

How to pivot on multiple columns

Posted on 2012-03-16
9
419 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
Highfive + Dolby Voice = No More Audio Complaints!

Poor audio quality is one of the top reasons people don’t use video conferencing. Get the crispest, clearest audio powered by Dolby Voice in every meeting. Highfive and Dolby Voice deliver the best video conferencing and audio experience for every meeting and every room.

 

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

How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

Join & Write a Comment

In this article I will describe the Detach & Attach method as one possible migration process and I will add the extra tasks needed for an upgrade when and where is applied so it will cover all.
This article explains how to reset the password of the sa account on a Microsoft SQL Server.  The steps in this article work in SQL 2005, 2008, 2008 R2, 2012, 2014 and 2016.
Familiarize people with the process of retrieving data from SQL Server using an Access pass-thru query. Microsoft Access is a very powerful client/server development tool. One of the ways that you can retrieve data from a SQL Server is by using a pa…
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.

758 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

17 Experts available now in Live!

Get 1:1 Help Now