Level Extreme platform
Subscription
Corporate profile
Products & Services
Support
Legal
Français
How to pivot this 2 tables?
Message
From
19/09/2015 14:39:41
 
 
To
19/09/2015 14:02:18
General information
Forum:
Microsoft SQL Server
Category:
SQL syntax
Environment versions
SQL Server:
SQL Server 2014
Application:
Web
Miscellaneous
Thread ID:
01624819
Message ID:
01624828
Views:
87
This message has been marked as the solution to the initial question of the thread.
OK, this (unfortunately) is a bit trickier when the list of columns is dynamic. By default, SQL Server Pivot isn't dynamic, so we need to use dynamic SQL.

Here's the full stored procedure. To test this, I had to create the tables and populate the rows. Here is the structure I used for the 2 tables. If your structure and columns are different, you'll need to adjust the query I have below.
CREATE TABLE dbo.QuoteMaster (  QuoteDate date, Client varchar(100),  NumQuotes int)
CREATE TABLE dbo.CancellationMaster  (CancelDate Date, Client varchar(100), Problem varchar(100), Qty int)   
OK, now for the stored procedure. It's at the end of this post at the bottom. I'm actually going to cover this more in detail as a blog post (from time to time I get questions about dynamic sql).

Basically, the proc does the following:

1)- Creates a temporary list (in a SQL common table expression subquery) of the possible columns. It hardwires 'quotes' as the first column, since you had a separate table for that, and then reads the rest by doing a SELECT DISTINCT of the Problem column from the Cancellation table.

2) - It builds a string from that subquery - a comma-separated string that uses brackets to delimit the columns, since the problem values had spaces in them That comma separated list will server as the basis for the dynamic SELECT and PIVOT. the FOR XML PATH ('') builds a basic XML string without any actual attribute names, and the STUFF replaces the first leading comma in the string with an empty value.

So at the end of that phase, the string has something like this:

[Quotes],[Declined at begining],[No Credit Card],[Not Ended]

3) - Then it constructs the dynamic PIVOT, by reading the source tables and the string from above.

The thing to remember with dynamic SQL is that you want to try to figure out what the "end result" would be, and then work backwards. The end result query we want to build, as a dynamic string, given your column values right now, would be as follows:
;WITH PIVOTCTE as 
 (select QuoteDate as ActivityDate, Client, 'Quotes' as ActionType,  NumQuotes as Qty  FROM dbo.QuoteMaster
UNION
 SELECT CancelDate as ActivityDate, Client, Problem as ActionType,  Qty from dbo.CancellationMaster)   


SELECT     ActivityDate, Client, [Quotes],[Declined at begining],[No Credit Card],[Not Ended] FROM PIVOTCTE 
            pivot ( SUM(Qty) for ActionType in ([Quotes],[Declined at begining],[No Credit Card],[Not Ended])) TEMPLIST
So....finally, here's the procedure you can use. This will read the data and build the necessary pivot statement, and execute it using dynamic sql.
CREATE PROCEDURE dbo.DynamicPivotExample
as
begin

  -- Strings to build, to execute dynamically
  DECLARE @ActionSelectString nvarchar(4000) , @SQLPivotQuery nvarchar(4000)
 
-- get a unique list of the possible Problem values

 ;WITH ListTempCTE as  
    (SELECT 'Quotes' AS ActionType , 1 as OrderNum    -- hard wire this one
			                   UNION
					      SELECT DISTINCT Problem as Actiontype, 2 as OrderNum FROM CancellationMaster )
  							 
-- build the ActionString for the problem values .  This will look like the following
-- [Quotes],[Declined at begining],[No Credit Card],[Not Ended]

 SELECT @ActionSelectString =  stuff (  (  select ',[' +  
           cast(ActionType as varchar(100))  + 
		    ']'                from  ListTempCTE
                      	ORDER BY OrderNum, ActionType
				  for xml path('') ), 1, 1, '')

-- Now build the entire query....which reads the quote master and the cancellationmaster....does a UNION to load them all together
-- so that we can have a basic PIVOT across all possible values

SET @SQLPivotQuery = ';WITH PIVOTCTE as 
 (select QuoteDate as ActivityDate, Client, ''Quotes'' as ActionType,  NumQuotes as Qty  FROM dbo.QuoteMaster
UNION
 SELECT CancelDate as ActivityDate, Client, Problem as ActionType,  Qty from dbo.CancellationMaster)  '

 set @SQLPivotQuery = @SqlPivotQuery + 
       ' SELECT     ActivityDate, Client, ' + @ActionSelectString +
     ' FROM PIVOTCTE 
            pivot ( SUM(Qty) for ActionType in ('
            +  @ActionSelectString + ')) TEMPLIST'

 EXEC sp_executesql @SqlPivotQuery
end
And then to execute it...

exec dbo.DynamicPivotExample
Previous
Next
Reply
Map
View

Click here to load this message in the networking platform