Please start any new threads on our new site at https://forums.sqlteam.com. We've got lots of great SQL Server experts to answer whatever question you can come up with.

 All Forums
 SQL Server 2005 Forums
 Transact-SQL (2005)
 complex pivot table script ~please, help

Author  Topic 

mmunson
Starting Member

10 Posts

Posted - 2009-06-01 : 14:06:48
Hello,

I was wondering if somenone could please tell me what's wrong with my pivot table script?

This is my script without the pivot table function:
use servicedw
--======Completed Confs parts & Qty=====--
SELECT DISTINCT
CRM_PartsLabor.TRANSACTION_ID as [Service Order ID]
, CRM_PartsLabor.ORDERED_PROD as [Part No]
, CRM_PartsLabor.DESCRIPTION as [Part Desc]
, CRM_Confirmations.POSTING_DATE as [Date Consumed]
, CRM_StatusCodes.USER_STATUS as [Part Status]
, CRM_PartsLabor.QUANTITY as [Quantity]
, CRM_StatusCodes.END_DATE as [Service Order Last Change]
, CRM_Orders.SERIAL as [Serial No]
, CRM_Partners.DESCRIPTION
, CRM_Partners.ADDRESS as [Role]
, CRM_Orders.PROCESS_TYPE

FROM
CRM_PartsLabor INNER JOIN CRM_Orders ON
CRM_PartsLabor.TRANSACTION_ID = CRM_Orders.TRANSACTION_ID
INNER JOIN CRM_StatusCodes ON CRM_Orders.TRANSACTION_ID = CRM_StatusCodes.TRANSACTION_ID
INNER JOIN CRM_Confirmations ON
CRM_StatusCodes.TRANSACTION_ID = CRM_Confirmations.TRANSACTION_ID
INNER JOIN CRM_Partners ON CRM_Orders.PARTNER_ID = CRM_Partners.PARTNER_ID
WHERE
CRM_PartsLabor.TRANSACTION_ID like ('3%')
and CRM_StatusCodes.user_STATUS = 'Complete'
and CRM_PartsLabor.ORDERED_PROD NOT IN ('AI','AP','BEAM0030_SVC_PLAN','BEAM0090_SVC_PLAN',
'BEAM0150_SVC_PLAN','BEAM0300_SVC_PLAN','BEAM0600_SVC_PLAN','BEAM1200_SVC_PLAN','CALLCENTER_LABOR',
'CLINICALAPPS_LABOR','CLINICALAPPS_TASK','DATA','DIST_SLF_APAC','DIST_TLC_APAC',
'FSE_LABOR','H-5007-0000','H-5008-0000','INSTALL_TASK_LIST','INSTALLATION_TASK',
'ISP_TASK','KB','MEDPHYSICS_LABOR','MEDPHYSICS_TASK','PARTNERSHIP_TLC','PROJECT_MNGT_TASK',
'SERVICE LABOR','TOTAL_TLC_EMEA','TOTAL_TLC_NA','WARRANTY_APAC','WARRANTY_DIST_APAC',
'WARRANTY_DIST_EMEA','WARRANTY_EMEA','WARRANTY_NA')
and CRM_Partners.PARTNER_FCT IN ('00000001','00000056','00000052')


And this is a sample of my result set:
Service Order ID | Part No | Part Desc | Date Consumed
3000000006 | 102031 | Upgrade, License, Windows Vista | 20090315
3000000006 | 102031 | Upgrade, License, Windows Vista | 20090315
3000000006 | 102031 | Upgrade, License, Windows Vista | 20090315
3000000006 | 102503 | Kit, Software Upgrade, 2.2.4 to | 20090315
3000000006 | 102503 | Kit, Software Upgrade, 3.1.4 to | 20090315
3000000006 | 102503 | Kit, Software Upgrade, 3.1.2 | 20090315

Part Status | Quantity | Service Order Last Change
Complete | 1 | 3/15/09 5:23 PM
Complete | 1 | 3/15/09 5:23 PM
Complete | 1 | 3/15/09 5:23 PM
Complete | 1 | 3/15/09 5:23 PM
Complete | 1 | 3/15/09 5:23 PM
Complete | 1 | 3/15/09 5:23 PM

Serial No | DESCRIPTION | Role | PROCESS_TYPE
110039 | Exec. Service Employee | Jeff A | ZSVO
110039 | Service Employee Group | CC CRM Global Call Center | ZSVO
110039 | Sold-To Party | Regional Medical Center | ZSVO
110039 | Exec. Service Employee | Jeff A | ZSVO
110039 | Service Employee Group | CC CRM Global Call Center | ZSVO
110039 | Sold-To Party | Regional Medical Center | ZSVO

As an example, I have part number 102031 on three lines but three different Descriptions and Roles. My goal is to make each of these in their own column so that I only have one line and not three.

This is an example:
PartNo | Exec. Service Employee| Service Employee Group | Sold-To Party
102031 | Jeff A. | CC CRM Global Call Center | Regional Medical Center
102503 | Jeff A. | CC CRM Global Call Center | Mercy Medical Center
5-903-61587 | Jeff A. | CC CRM Global Call Center | John Hopkins Medical Center

So, you can see I have each part number on it's own line and the Exec. Service Employee, Service Employee Group, Sold-To Party as a column and not in rows anymore.

Here's the script that's supposed to make it work. But I've spent a week trying to make it work with the rest of my script.

--===== Conditionally drop, then recreate and populate the test table.
-- None of this is part of the solution. It just provides a
-- test bed for the coded solution that follows this section.
IF OBJECT_ID('TempDB..#PivotExample') IS NOT NULL
DROP TABLE #PivotExample
CREATE TABLE #PivotExample (PartNo VARCHAR(12),RoleDesc VARCHAR(64))
INSERT INTO #PivotExample
SELECT '102031' , 'Exec. Service Employee, Jeff A.' UNION ALL
SELECT '102031' , 'Service Employee Group, Global Call Center' UNION ALL
SELECT '102031' , 'Sold-To Party, McLaren Center' UNION ALL
SELECT '102503' , 'Exec. Service Employee, Jeff A.' UNION ALL
SELECT '102503' , 'Service Employee Group, Global Call Center' UNION ALL
SELECT '102503' , 'Sold-To Party, Center' UNION ALL
SELECT '5-903-61587', 'Exec. Service Employee, Jeff A.' UNION ALL
SELECT '5-903-61587', 'Service Employee Group, Global Call Center' UNION ALL
SELECT '5-903-61587', 'Sold-To Party, Center'

--===== Solution starts here
--===== Conditionally drop the work table
IF OBJECT_ID('Tempdb..#NormalNVP') IS NOT NULL
DROP TABLE #NormalNVP

--===== Declare the dynamic SQL Variables
DECLARE @SQLSelect VARCHAR(8000),
@SQLSelectList VARCHAR(8000),
@SQLFrom VARCHAR(8000)

--===== Split the RoleDesc and save the data in a temp table because
-- we're going to use it more than once. We could use the a
-- CTE twice, but the code for it would be executed twice and
-- it would simply make life a bit more difficult. Temp table
-- is a lot easier here because it allows for very simple
-- "Divide'n'Conquer" programming... might be faster, too.
SELECT *
INTO #NormalNVP
FROM (--==== Split the RoleDesc column like it should have been split in the
-- original NVP (Name/Value Pair) table.
SELECT PartNo,
SUBSTRING(RoleDesc,1,CHARINDEX(',',RoleDesc)-1) AS NVPRole,
SUBSTRING(RoleDesc,CHARINDEX(',',RoleDesc)+2,8000) NVPValue
FROM #PivotExample
) d

--===== Create the static part of the SELECT
SELECT @SQLSelect = ' SELECT PartNo,' + CHAR(10)

--===== Create the dynamic SELECT list
SELECT @SQLSelectList = ISNULL(@SQLSelectList + ',' + CHAR(10),'') + SPACE(8)
+ 'MAX(CASE WHEN NVPRole = ' + QUOTENAME(NVPRole,'''')
+ ' THEN NVPValue END) AS ' + QUOTENAME(NVPRole)
FROM #NormalNVP
GROUP BY NVPRole

--===== Create the static FROM clause
SELECT @SQLFrom = '
FROM #NormalNVP
GROUP BY PartNo
ORDER BY PartNo
'
--===== Display the Dynmamic SQL we just created
PRINT @SQLSelect + @SQLSelectList + @SQLFrom

--===== Execute the Dynamic SQL to solve the problem
EXEC (@SQLSelect + @SQLSelectList + @SQLFrom)


I started out like this, but I'm gettign this error:
Msg 156, Level 15, State 1, Line 31
Incorrect syntax near the keyword 'SELECT'.
Msg 102, Level 15, State 1, Line 35
Incorrect syntax near ')'.

--===== Solution starts here
--===== Conditionally drop the work table
IF OBJECT_ID('Tempdb..#NormalNVP') IS NOT NULL
DROP TABLE #NormalNVP

--===== Declare the dynamic SQL Variables
DECLARE @SQLSelect VARCHAR(8000),
@SQLSelectList VARCHAR(8000),
@SQLFrom VARCHAR(8000)

--===== Split the RoleDesc and save the data in a temp table because
-- we're going to use it more than once. We could use the a
-- CTE twice, but the code for it would be executed twice and
-- it would simply make life a bit more difficult. Temp table
-- is a lot easier here because it allows for very simple
-- "Divide'n'Conquer" programming... might be faster, too.
SELECT CRM_PartsLabor.TRANSACTION_ID AS [Service Order ID], CRM_PartsLabor.ORDERED_PROD AS [Part No],
CRM_PartsLabor.DESCRIPTION AS [Part Desc], CRM_Confirmations.POSTING_DATE AS [Date Consumed],
CRM_StatusCodes.USER_STATUS AS [Part Status], CRM_PartsLabor.QUANTITY AS Quantity,
CRM_StatusCodes.END_DATE AS [Service Order Last Change], CRM_Orders.SERIAL AS [Serial No], CRM_Orders.PROCESS_TYPE,
CRM_Partners.PARTNER_FCT, CRM_Partners.DESCRIPTION, CRM_Partners.ADDRESS
INTO [#NormalNVP]
FROM CRM_PartsLabor INNER JOIN
CRM_Orders ON CRM_PartsLabor.TRANSACTION_ID = CRM_Orders.TRANSACTION_ID INNER JOIN
CRM_StatusCodes ON CRM_Orders.TRANSACTION_ID = CRM_StatusCodes.TRANSACTION_ID INNER JOIN
CRM_Confirmations ON CRM_StatusCodes.TRANSACTION_ID = CRM_Confirmations.TRANSACTION_ID INNER JOIN
CRM_Partners ON CRM_Orders.PARTNER_ID = CRM_Partners.PARTNER_ID select * from #NormalNVP

(--==== Split the RoleDesc column like it should have been split in the
-- original NVP (Name/Value Pair) table.
SELECT [Part No],
SUBSTRING(RoleDesc,1,CHARINDEX(',',RoleDesc)-1) AS NVPRole,
SUBSTRING(RoleDesc,CHARINDEX(',',RoleDesc)+2,8000) NVPValue
FROM #PivotExample
) d

--===== Create the static part of the SELECT
SELECT @SQLSelect = ' SELECT PartNo,' + CHAR(10)

--===== Create the dynamic SELECT list
SELECT @SQLSelectList = ISNULL(@SQLSelectList + ',' + CHAR(10),'') + SPACE(8)
+ 'MAX(CASE WHEN NVPRole = ' + QUOTENAME(NVPRole,'''')
+ ' THEN NVPValue END) AS ' + QUOTENAME(NVPRole)
FROM #NormalNVP
GROUP BY NVPRole

--===== Create the static FROM clause
SELECT @SQLFrom = '
FROM #NormalNVP
GROUP BY PartNo
ORDER BY PartNo
'
--===== Display the Dynmamic SQL we just created
PRINT @SQLSelect + @SQLSelectList + @SQLFrom

--===== Execute the Dynamic SQL to solve the problem
EXEC (@SQLSelect + @SQLSelectList + @SQLFrom)


I just simply don't know what to do anymore and I have to get this working, I'M DESPERATE!

If someone could please tell me how to do this I would be forever grateful!!

Thank you in advance! ~Michelle

visakh16
Very Important crosS Applying yaK Herder

52326 Posts

Posted - 2009-06-01 : 14:14:51
you've not specified how the three tables are related to each other. by which field?
Go to Top of Page

mmunson
Starting Member

10 Posts

Posted - 2009-06-01 : 14:24:37
quote:
Originally posted by visakh16

you've not specified how the three tables are related to each other. by which field?



Hi Visakh16,

I hope this clarifies your question....

Part No is from the CRM_PartsLabor table and Exec. Service Employee, Service Employee Group and Sold-To-Party is from the crm_partners table. The three fields from teh crm_partners table are all on two columns, one that contains the 'title' and the other that contains the actual 'name'.

PartNo | Exec. Service Employee | Service Employee Group | Sold-To Party
102031 | Jeff A. | Global Call Center | Regional Center
102503 Jeff A. | Global Call Center | Mercy Center
5-903-61587 | Jeff A. | Global Call Center | Johns Hopkins Medical Center

In my original script these are the joins I used.
FROM
CRM_PartsLabor INNER JOIN CRM_Orders ON
CRM_PartsLabor.TRANSACTION_ID = CRM_Orders.TRANSACTION_ID
INNER JOIN CRM_StatusCodes ON CRM_Orders.TRANSACTION_ID = CRM_StatusCodes.TRANSACTION_ID
INNER JOIN CRM_Confirmations ON
CRM_StatusCodes.TRANSACTION_ID = CRM_Confirmations.TRANSACTION_ID
INNER JOIN CRM_Partners ON CRM_Orders.PARTNER_ID = CRM_Partners.PARTNER_ID


Did this make sense? Does this answer your question? I'm a bit of a newbie still....

Thank you! ~Michelle
Go to Top of Page

visakh16
Very Important crosS Applying yaK Herder

52326 Posts

Posted - 2009-06-01 : 14:30:21
[code]
SELECT CRM_PartsLabor.ORDERED_PROD as [Part No]
, MAX(CASE WHEN CRM_PartsLabor.DESCRIPTION ='Exec. Service Employee' THEN CRM_Partners.ADDRESS ELSE NULL END) as [Exec. Service Employee],
MAX(CASE WHEN CRM_PartsLabor.DESCRIPTION ='Service Employee Group' THEN CRM_Partners.ADDRESS ELSE NULL END) as [Service Employee Group],
MAX(CASE WHEN CRM_PartsLabor.DESCRIPTION ='Sold-To Party' THEN CRM_Partners.ADDRESS ELSE NULL END) as [Sold-To Party]
FROM
CRM_PartsLabor INNER JOIN CRM_Orders ON
CRM_PartsLabor.TRANSACTION_ID = CRM_Orders.TRANSACTION_ID
INNER JOIN CRM_StatusCodes ON CRM_Orders.TRANSACTION_ID = CRM_StatusCodes.TRANSACTION_ID
INNER JOIN CRM_Confirmations ON
CRM_StatusCodes.TRANSACTION_ID = CRM_Confirmations.TRANSACTION_ID
INNER JOIN CRM_Partners ON CRM_Orders.PARTNER_ID = CRM_Partners.PARTNER_ID
WHERE
CRM_PartsLabor.TRANSACTION_ID like ('3%')
and CRM_StatusCodes.user_STATUS = 'Complete'
and CRM_PartsLabor.ORDERED_PROD NOT IN ('AI','AP','BEAM0030_SVC_PLAN','BEAM0090_SVC_PLAN',
'BEAM0150_SVC_PLAN','BEAM0300_SVC_PLAN','BEAM0600_SVC_PLAN','BEAM1200_SVC_PLAN','CALLCENTER_LABOR',
'CLINICALAPPS_LABOR','CLINICALAPPS_TASK','DATA','DIST_SLF_APAC','DIST_TLC_APAC',
'FSE_LABOR','H-5007-0000','H-5008-0000','INSTALL_TASK_LIST','INSTALLATION_TASK',
'ISP_TASK','KB','MEDPHYSICS_LABOR','MEDPHYSICS_TASK','PARTNERSHIP_TLC','PROJECT_MNGT_TASK',
'SERVICE LABOR','TOTAL_TLC_EMEA','TOTAL_TLC_NA','WARRANTY_APAC','WARRANTY_DIST_APAC',
'WARRANTY_DIST_EMEA','WARRANTY_EMEA','WARRANTY_NA')
and CRM_Partners.PARTNER_FCT IN ('00000001','00000056','00000052')
GROUP BY CRM_PartsLabor.ORDERED_PROD
[/code]
[/code]
Go to Top of Page

mmunson
Starting Member

10 Posts

Posted - 2009-06-01 : 15:11:47
Wow, I didn't think of that approach visakh16!

I made a couple of changes and it works wonderfully!!!

Thank you so much Visakh16, you saved me!

~Michelle
Go to Top of Page
   

- Advertisement -