Solved

Pivot SQL Query

Posted on 2014-01-12
8
266 Views
Last Modified: 2014-01-12
This query list each contributor by year. What I would like is to see

Contributor   Year 1  Year 2  Year 3 Year 4

For example:
Contributor   Year 1  Year 2  Year 3 Year 4
100                 $100      $200   $300  $400
200                   $50      $100   $150  $200


SELECT year(t2.date) as YearContrib,t2.MemberNumberId,sum(coalesce([Amount],0)) as Amount
FROM [Contribution Details] t1
inner join [Contribution Headers] t2 on t1.ContribHeaderId=t2.ContribNumberId
group by t2.MemberNumberId,year(t2.date)      
order by MemberNumberId,year(t2.date)

How do I restructure this query to accomplish this? I am using SQL Server 2012
0
Comment
Question by:rwheeler23
[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
  • 4
  • 4
8 Comments
 
LVL 16

Expert Comment

by:Surendra Nath
ID: 39775112
as long as you have only 4 years in the selection criteria then you can use the below approach

;with C AS
(
SELECT year(t2.date) as YearContrib,t2.MemberNumberId,sum(coalesce([Amount],0)) as Amount
FROM [Contribution Details] t1
inner join [Contribution Headers] t2 on t1.ContribHeaderId=t2.ContribNumberId
group by t2.MemberNumberId,year(t2.date)      
)
select MemberNumID as contributerID,[2009],[2010],[2011],[2012]
FROM 
(
  SELECT * FROM C
)
PIVOT
(
  SUM(Amount) FOR MemberNumID IN ([2009],[2010],[2011],[2012])
) as pvt 
order by 1

Open in new window


incase if the number of years are dynamic and you don't know what they will be then you have to use a dynamic PIVOT as we do below



DECLARE @SQL VARCHAR(3000)
DECLARE @SQ VARCHAR(4) = ''''
;with C AS
(
SELECT year(t2.date) as YearContrib,t2.MemberNumberId,sum(coalesce([Amount],0)) as Amount
FROM [Contribution Details] t1
inner join [Contribution Headers] t2 on t1.ContribHeaderId=t2.ContribNumberId
group by t2.MemberNumberId,year(t2.date)      
), D AS
(
 SELECT DISTINCT YearContrib FROM C
), E AS
(
SELECT STUFF( (SELECT ',' + '[' + YearContrib + ']'  as Y FROM D FOR XML PATH ('')),1,1,'')
)
SELECT @SQL = 
'
;with C AS
(
SELECT year(t2.date) as YearContrib,t2.MemberNumberId,sum(coalesce([Amount],0)) as Amount
FROM [Contribution Details] t1
inner join [Contribution Headers] t2 on t1.ContribHeaderId=t2.ContribNumberId
group by t2.MemberNumberId,year(t2.date)      
)
' + 
'
select MemberNumID as contributerID, ' + (SELECT Y FROM D) + 
FROM 
(
  SELECT * FROM C
)
PIVOT
(
  SUM(Amount) FOR MemberNumID IN ( ' + (SELECT Y FROM D) + ')
) as pvt 
order by 1 '

Open in new window

0
 

Author Comment

by:rwheeler23
ID: 39775158
The query give me this message:

Msg 156, Level 15, State 1, Line 13
Incorrect syntax near the keyword 'PIVOT'.

And the second one gives me:

Msg 156, Level 15, State 1, Line 28
Incorrect syntax near the keyword 'FROM'.
Msg 156, Level 15, State 1, Line 32
Incorrect syntax near the keyword 'PIVOT'.
0
 
LVL 16

Expert Comment

by:Surendra Nath
ID: 39775173
check this out

;with C AS
(
SELECT year(t2.date) as YearContrib,t2.MemberNumberId,sum(coalesce([Amount],0)) as Amount
FROM [Contribution Details] t1
inner join [Contribution Headers] t2 on t1.ContribHeaderId=t2.ContribNumberId
group by t2.MemberNumberId,year(t2.date)      
)
select MemberNumID as contributerID,[2009],[2010],[2011],[2012]
FROM 
(
  SELECT * FROM C
) as p
PIVOT
(
  SUM(Amount) FOR MemberNumID IN ([2009],[2010],[2011],[2012])
) as pvt 
order by 1

Open in new window

0
Industry Leaders: 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!

 

Author Comment

by:rwheeler23
ID: 39775196
Now I get these:

Msg 207, Level 16, State 1, Line 15
Invalid column name 'MemberNumID'.
Msg 207, Level 16, State 1, Line 8
Invalid column name 'MemberNumID'.
0
 
LVL 16

Accepted Solution

by:
Surendra Nath earned 500 total points
ID: 39775206
My Mistake used improper column name, use the below

;with C AS
(
SELECT year(t2.date) as YearContrib,t2.MemberNumberId,sum(coalesce([Amount],0)) as Amount
FROM [Contribution Details] t1
inner join [Contribution Headers] t2 on t1.ContribHeaderId=t2.ContribNumberId
group by t2.MemberNumberId,year(t2.date)      
)
select MemberNumberId as contributerID,[2009],[2010],[2011],[2012]
FROM 
(
  SELECT * FROM C
) as p
PIVOT
(
  SUM(Amount) FOR YearContrib IN ([2009],[2010],[2011],[2012])
) as pvt 
order by 1

Open in new window

0
 

Author Comment

by:rwheeler23
ID: 39775233
This is brilliant. Thank you so much. I have seen this construct before but never fully understood it.

May I asked what does the

;with C AS

do?
0
 
LVL 16

Expert Comment

by:Surendra Nath
ID: 39775240
it is called Common Table Expression, commonly abbreviated as CTE's... they can be used in various number of places...
0
 

Author Closing Comment

by:rwheeler23
ID: 39775254
Thank you so very much! Very clear and concise solution and follow up was excellent.
0

Featured Post

Visualize your virtual and backup environments

Create well-organized and polished visualizations of your virtual and backup environments when planning VMware vSphere, Microsoft Hyper-V or Veeam deployments. It helps you to gain better visibility and valuable business insights.

Question has a verified solution.

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

Why is this different from all of the other step by step guides?  Because I make a living as a DBA and not as a writer and I lived through this experience. Defining the name: When I talk to people they say different names on this subject stuff l…
JSON is being used more and more, besides XML, and you surely wanted to parse the data out into SQL instead of doing it in some Javascript. The below function in SQL Server can do the job for you, returning a quick table with the parsed data.
This video shows, step by step, how to configure Oracle Heterogeneous Services via the Generic Gateway Agent in order to make a connection from an Oracle session and access a remote SQL Server database table.
Via a live example, show how to extract insert data into a SQL Server database table using the Import/Export option and Bulk Insert.

737 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