Solved

SQL Pivot

Posted on 2010-08-13
8
724 Views
Last Modified: 2012-08-13
I have data in a table that I need to do a PIVOT on

Currently

TYPE      Jan     Feb   Mar   ....
Apd         1          2       0
Rsd          2         1        3

I need

Month        Apd       Rsd
Jan              1           2
Feb             2            1
Mar             0            3
0
Comment
Question by:lrbrister
[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
  • 2
  • 2
8 Comments
 
LVL 60

Accepted Solution

by:
Kevin Cross earned 350 total points
ID: 33434133
lrbrister,

It looks like first you need to unpivot on the month and then pivot on the type. Sorting will be a different story as you have text months, so you will have to equate Jan to 1 ... and as you can see you will have to completely fill in (hard-code) the other months and other types in the pivot statements. If you need this to be dynamic for [type] then you need to use dynamic SQL. For the sort, I recommend you have a table of months short name with associated month number then you can use that to sort efficiently.
select *
from (

select [type], [value], [month]
from your_table_name
unpivot(value for [month] in (Jan, Feb, Mar)) u

) d
pivot(sum(value) for [type] in (Apd, Rsd))p
;

Open in new window

0
 
LVL 7

Assisted Solution

by:rmm2001
rmm2001 earned 150 total points
ID: 33437698
going on what mwvisa1 said...here's how you could make it dynamic. the first query pulls the values in the type table and makes them in a delimited list, The second one goes and makes your column headings into a delimited list. the 3rd one is a dynamic version of what mwvist1 posted.


----get the different types
DECLARE @typequery NVARCHAR(4000)
DECLARE @typenames NVARCHAR(4000)
SET @typequery = '
   ;WITH CTE ( CategoryId, typenames, type, length ) 
          AS ( SELECT DISTINCT 1 CategoryId, CAST( '''' AS VARCHAR(8000) ), CAST( '''' AS VARCHAR(8000)) type, 0
                 FROM table0
                GROUP BY type
                UNION ALL
               SELECT 1 CategoryId, CAST( p.[type] + 
                      CASE WHEN length = 0 THEN '''' ELSE '', '' END + typenames AS VARCHAR(8000) ), 
                      CAST( p.[type]  AS VARCHAR(8000)), length + 1
                 FROM CTE c
                JOIN table0 p
                   ON p.type > c.type) 
    SELECT @typenames = typenames 
      FROM ( 
      SELECT CategoryId, typenames, 
                    RANK() OVER ( PARTITION BY CategoryId ORDER BY length DESC )
               FROM CTE  ) D ( CategoryId, typenames, rank )
     WHERE rank = 1 '
   
EXEC sp_executesql
@typequery,
N'@typenames NVARCHAR(4000) OUTPUT', 
@typenames OUTPUT

----now get the columns 
DECLARE @colsquery NVARCHAR(4000)
DECLARE @cols NVARCHAR(4000)
SET @colsquery = '
			SELECT @cols = LEFT(cols, LEN(cols) - 1)
			FROM information_schema.columns p1
		    CROSS APPLY ( SELECT column_name + '',''
							 FROM information_schema.columns p2
							 WHERE p2.table_name = p1.table_name AND column_name <> ''Type''
							 ORDER BY table_name
							 FOR XML PATH('''') )  D ( cols )
			WHERE table_name = ''table0''
'
EXEC sp_executesql
@colsquery,
N'@cols NVARCHAR(4000) OUTPUT',
@cols OUTPUT
SELECT @cols

----execute the pivot query
DECLARE @pivotquery NVARCHAR(4000)
SET @pivotquery = '
SELECT *
FROM (

	SELECT [type], [value], [month]
	FROM table0
	UNPIVOT(value FOR [month] IN (' + @cols + ' )) u

) d
PIVOT(SUM(value) FOR [type] IN (' + @typenames + '))p
;'
EXEC sp_executesql
@pivotquery

Open in new window

0
 

Author Comment

by:lrbrister
ID: 33444725
rmm2001:
I'm not "getting it" for some reason.
Take a look at my screenprint...that's what I need to "unpivot so that the rows are the columns and vice versa...

screenprint.jpg
0
[Live Webinar] The Cloud Skills Gap

As Cloud technologies come of age, business leaders grapple with the impact it has on their team's skills and the gap associated with the use of a cloud platform.

Join experts from 451 Research and Concerto Cloud Services on July 27th where we will examine fact and fiction.

 
LVL 7

Expert Comment

by:rmm2001
ID: 33444758
try what mwvista1 said. that should get you what you want i think. the thing i posted was to make it dynamic so don't have to type in every single field for the pivot/unpivot commands. you'd just type in the table name.


select *
from (

select [type], [value], [month]
from your_table_name
unpivot(value for [month] in (Jan, Feb, Mar)) u

) d
pivot(sum(value) for [type] in (Apd, Rsd))p
;

Open in new window

0
 

Author Comment

by:lrbrister
ID: 33444978
Ok folks...getting there...
Theonly issue I have is that it's not sorting the months
 
The select below returns...
ahoffman Apr 0 0
ahoffman Aug 0 1
ahoffman Dec 0 0
ahoffman Feb 0 0
ahoffman Jan 0 0
ahoffman Jul 11 5
ahoffman Jun 3 3

select *  
from (  
  
select [rep],[EventType], [value], [month]  
from dbo.tblRepScoreCard
unpivot(value for [month] in (Jan, Feb, Mar,Apr,May,Jun,Jul,Aug,Sept,Oct,Nov,Dec)) u  
  
) d  
pivot(sum(value) for [EventType] in (PASigned, PAComplete))p  
order by p.rep, p.month
;

Open in new window

0
 

Author Comment

by:lrbrister
ID: 33445131
hey folks...
I got it.  Used most of mwvisa1: and a touch of rmm2001 in the final solution (Attached)
mwvisa1...you mind a 350-150 split with  rmm2001?

select *
from (  
  
select [rep],[EventType], [value], [month]  
from dbo.tblRepScoreCard
unpivot(value for [month] in (Jan, Feb, Mar,Apr,May,Jun,Jul,Aug,Sept,Oct,Nov,Dec)) u  
  
) d  
pivot(sum(value) for [EventType] in (PASigned, PAComplete, Dropped, Funded))p  
order by p.rep, CHARINDEX(Left(p.[month],3),'xxJANFEBMARAPRMAYJUNJULAUGSEPOCTNOVDEC')/3
;

Open in new window

0
 
LVL 60

Expert Comment

by:Kevin Cross
ID: 33445164
A split is perfectly fine by me. Just glad I could help!

Best regards and happy coding,
Kevin
0
 

Author Closing Comment

by:lrbrister
ID: 33445243
Excellent folks...thanks
0

Featured Post

Ready to get started with anonymous questions?

It's easy! Check out this step-by-step guide for asking an anonymous question on Experts Exchange.

Question has a verified solution.

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

Recently we ran in to an issue while running some SQL jobs where we were trying to process the cubes.  We got an error saying failure stating 'NT SERVICE\SQLSERVERAGENT does not have access to Analysis Services. So this is a way to automate that wit…
In part one, we reviewed the prerequisites required for installing SQL Server vNext. In this part we will explore how to install Microsoft's SQL Server on Ubuntu 16.04.
Via a live example, show how to shrink a transaction log file down to a reasonable size.
Viewers will learn how to use the INSERT statement to insert data into their tables. It will also introduce the NULL statement, to show them what happens when no value is giving for any given column.

632 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