Solved

SQL Pivot

Posted on 2010-08-13
8
699 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
  • 4
  • 2
  • 2
8 Comments
 
LVL 59

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
 
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
Complete Microsoft Windows PC® & Mac Backup

Backup and recovery solutions to protect all your PCs & Mac– on-premises or in remote locations. Acronis backs up entire PC or Mac with patented reliable disk imaging technology and you will be able to restore workstations to a new, dissimilar hardware in minutes.

 

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 59

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

Better Security Awareness With Threat Intelligence

See how one of the leading financial services organizations uses Recorded Future as part of a holistic threat intelligence program to promote security awareness and proactively and efficiently identify threats.

Join & Write a Comment

Suggested Solutions

Title # Comments Views Activity
Query table for min date and unique user in SQL SERVER 8 81
sql server query? 6 28
Mssql SQL query 14 28
select over clause 1 10
In this article we will get to know that how can we recover deleted data if it happens accidently. We really can recover deleted rows if we know the time when data is deleted by using the transaction log.
Load balancing is the method of dividing the total amount of work performed by one computer between two or more computers. Its aim is to get more work done in the same amount of time, ensuring that all the users get served faster.
Familiarize people with the process of utilizing SQL Server functions from within Microsoft Access. Microsoft Access is a very powerful client/server development tool. One of the SQL Server objects that you can interact with from within Microsoft Ac…
Via a live example, show how to set up a backup for SQL Server using a Maintenance Plan and how to schedule the job into SQL Server Agent.

747 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

12 Experts available now in Live!

Get 1:1 Help Now