How to Perform Explicit Conversion in Dynamic Pivot - sql

How to Perform Explicit Conversion in Dynamic Pivot.
I need to convert datatype for single field.
This is my sample query
SELECT #cols = STUFF((SELECT ',' + (QUOTENAME(P.ColumnName))from #temp as p
JOIN information_schema.columns as C ON P.ColumnName=C.column_name
where C.table_name='tablename'
SET #query = 'SELECT ' + #cols + 'from (select ColumnVlaue, ColumnName from #temp) x
pivot(max(ColumnVlaue) for ColumnName in (' + #cols + ')) p '
EXECUTE(#query)

You do it when you build the #cols variable.
Actually you need a second #cols variable #cols2 that holds the columns with the cast expression.
If #cols contains Col1, Col2 then #Cols2 should be cast(Col1 as int) as Col1, cast(Col2 as int) as Col2
Use #Cols2 in the select column list and #Cols in the pivot column list.
SET #query = 'SELECT ' + #cols2 + 'from (select ColumnVlaue, ColumnName from #temp) x
pivot(max(ColumnVlaue) for ColumnName in (' + #cols + ')) p '
EXECUTE(#query)

Related

Declare a Table Variable based on dynamic pivot columns statement

I want to declare a table variable and fill it from the pivot with dynamic column to perform join statement.
DECLARE #cols AS NVARCHAR(MAX), #query AS NVARCHAR(MAX)
SELECT #cols =
STUFF((SELECT DISTINCT ',' + QUOTENAME(ColName)
FROM [sbs].[ProposalAmounts]
GROUP BY ColName, ProposalID
FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'),1,1,'')
SET #query = N'SELECT ProposalID, ' + #cols + N' from
(select ProposalID, Amount, ColName from [sbs].[ProposalAmounts]) x
PIVOT
(MAX(Amount)for ColName in (' + #cols + N')) p '
EXEC sp_executesql #query;
This is what I've done so far and I'm confused as to how to declare a table variable that has dynamic columns in it.
This is the result of the query above:
And this is the result of the table I want to perform join statement:
Like Jeroen Mostert commented, you need to make everything dynamic.
I would suggest to put the join inside the dynamic query. Instead of a table variable, I use a common table expression.
DECLARE #cols AS NVARCHAR(MAX), #query AS NVARCHAR(MAX);
SELECT #cols =
STUFF((SELECT DISTINCT N', ' + QUOTENAME([ColName])
FROM [_tmp_].[ProposalAmounts]
GROUP BY [ColName], [ProposalID]
FOR XML PATH(N''), TYPE).value(N'.', N'NVARCHAR(MAX)'), 1, 2, N'')
SET #query = N'
WITH [CTE_Pivoted_ProposalAmounts] AS
(
SELECT [ProposalID], ' + #cols + N'
FROM
(SELECT [ProposalID], [Amount], [ColName] FROM [sbs].[ProposalAmounts]) x
PIVOT (MAX([Amount]) FOR [ColName] IN (' + #cols + N')) p
)
SELECT *
FROM
[sbs].[OtherTable] ot
INNER JOIN [CTE_Pivoted_ProposalAmounts] ppa ON ppa.[ProposalID] = ot.[ProposalID];
';
EXEC sp_executesql #query;
You need to replace [sbs].[OtherTable] with the actual name of the table you want to join with. And you might also tweak the join criteria and the fields in the SELECT clause. This code here is just a simple example. I assume you will manage to fix the query yourself to make it behave as you expect.

Pivoting Issue (what am I missing)?

Trying to pivot data and add a calculated column to no avail.
I have tried the enclosed code below but cannot get exactly what I am after.
My table consists of three columns
TABLE_NAME, REPORT_DATE, COUNT_ROWS
For the last two [REPORT_DATE]s, I am trying to show in a pivot the [COUNT_ROWS] for each [TABLE_NAME]
What am I missing? Additionally, how would I go about adding a column subtracting the values between the two dates in the pivot?
DECLARE #cols AS NVARCHAR(MAX)='';
DECLARE #query AS NVARCHAR(MAX)='';
SELECT #cols = #cols + QUOTENAME(REPORT_DATE) + ',' FROM (select DISTINCT TOP 2 REPORT_DATE from account_report order by REPORT_DATE desc) as tmp
select #cols = substring(#cols, 0, len(#cols)) --trim "," at end
set #query =
'SELECT * from
(select [TABLE_NAME], [COUNT_ROWS] from account_report
) src
pivot
(sum([COUNT_ROWS]) for [TABLE_NAME] in (' + #cols + ')
) piv'
execute(#query)
All I am getting from the script is a two column result of the two [REPORT_DATE]s with 1 row showing null values (although my data does include rows)
I bet you are trying to get the following out of the query:
SELECT * from
(select [TABLE_NAME], [COUNT_ROWS], [REPORT_DATE] from account_report
) src
pivot
(sum([COUNT_ROWS]) for [REPORT_DATE] in (' + #cols + ')
) piv
Conversely, if you really want the report name pushed out columnwise then you need to adjust your #cols variable.
SELECT #cols = #cols + QUOTENAME(TABLE_NAME) + ',' FROM (select DISTINCT TOP 2 TABLE_NAME ,REPORT_DATE from account_report order by REPORT_DATE desc) as tmp
select #cols = substring(#cols, 0, len(#cols)) --trim "," at end
set #query =
'SELECT * from
(select [REPORT_DATE], [TABLE_NAME], [COUNT_ROWS] from account_report
) src
pivot
(sum([COUNT_ROWS]) for [TABLE_NAME] in (' + #cols + ')
) piv'
execute(#query)

Summing multiple dynamically declared variables (fast)

I'm developing a program where I have multiple columns which I need to show the sum of to anEnd-user. These columns are assigned in the table ColumnTest in the column ColumnNames and their names can be changed by the user. Therefore I need to look up all the column names in ColumnTest\ColumnNames and afterwards sum all values regarding these columnnames from the outputtable.
I have previously used this script where I get all the columnnames in #cols like this [col1].[col2].[col3] and so on, but when I try to run the query I'm not able to sum these columns using '+ #cols + '. When I run this I get the following error: The SUM function requires 1 argument(s). Is there a viable option to do this procedure, without compromising the loading-time substantially?
DECLARE
#cols AS NVARCHAR(MAX),
#query AS NVARCHAR(MAX);
SELECT #cols = STUFF((SELECT distinct ',' + QUOTENAME(c.ColumnNames)
FROM ColumnTest c
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)') ,1,1,'')
set #query =
'
SELECT
ID
,SUM('+ #cols + ')
FROM Output_table
GROUP BY
ID
'
execute(#query);
Try this,
DECLARE
#cols AS NVARCHAR(MAX)='',
#query AS NVARCHAR(MAX);
SELECT #cols += 'SUM('+ColumnNames+') as ['+ColumnNames+'],'
from
(
SELECT distinct ColumnNames FROM ColumnTest
)A
SELECT #cols=LEFT(#cols,LEN(#cols)-1)
set #query =
'
SELECT ID,'+ #cols + '
FROM Output_table
GROUP BY ID
'
execute(#query);
or if you want addition of all column values you can use below query
DECLARE #cols AS NVARCHAR(MAX)='',
#query AS NVARCHAR(MAX);
SELECT #cols += ''+ColumnNames+'+'
FROM
(
SELECT DISTINCT ColumnNames FROM ColumnTest
)A
SELECT #cols=LEFT(#cols,LEN(#cols)-1)
set #query =
'
SELECT ID,SUM('+ #cols + ')
FROM Output_table
GROUP BY ID
'
execute(#query);
You can not use comma separated like ','
You can use '+'
Try this
DECLARE
#cols AS NVARCHAR(MAX),
#query AS NVARCHAR(MAX);
SELECT #cols = STUFF((SELECT distinct '+' + QUOTENAME(c.ColumnNames)
FROM ColumnTest c
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)') ,1,1,'')
set #query =
'
SELECT
ID
,SUM('+ #cols + ')
FROM Output_table
GROUP BY
ID
'
execute(#query);

SQL - Pivoting on Column and Row Values

I'm trying to Pivot a Table on X and Y position. The table is in a format similar to below.
Each row has a value which is relative to its Row and Column Position.'AThing' and 'FileName' are to be ignored in the data set.
So if this was pivoted we would get:
Iv'e been trying for a while but can't seem to figure it out, any ideas?
EDIT: Number of Fields are dynamic per 'FileName'. I have managed to extract the column names but not the data using:
-- Construct List of Columns to Pivot
SELECT #PivotCols =
STUFF(
(SELECT ',' + QUOTENAME(FieldName)
FROM #Data
GROUP BY ColPos, FieldName
ORDER BY ColPos ASC
FOR XML PATH(''),TYPE).value('.', 'NVARCHAR(MAX)')
,1,1,'')
SET #PivotQuery =
SELECT ' + #PivotCols + N'
FROM
(
SELECT ColPos, FieldName
FROM #Data
GROUP BY ColPos, FieldName
) x
PIVOT
(
MIN(ColPos)
FOR FieldName IN (' + #PivotCols + N')
) p'
EXEC sp_executesql #PivotQuery
Please try this code:
DECLARE #columns NVARCHAR(MAX), #sql NVARCHAR(MAX);
SET #columns = N'';
SELECT #columns += N', p.' + QUOTENAME(FieldName)
FROM (SELECT distinct p.FieldName FROM Tablename AS p
) AS x;
SET #sql = N'
SELECT ' + STUFF(#columns, 1, 2, '') + '
FROM
(
SELECT p.Value, p.FieldName, p.RowPos
FROM Tablename AS p
) AS j
PIVOT
(
MAX(Value) FOR FieldName IN ('
+ STUFF(REPLACE(#columns, ', p.[', ',['), 1, 1, '')
+ ')
) AS p;';
PRINT #sql;
EXEC sp_executesql #sql;

SQL Pivot Query

I have the below data in SQL:
Now, I would like to pivot it base on the "CostCenterNumber" field to obtain this:
Try this one:
DECLARE #cols as varchar(max)
DECLARE #sql as varchar(max)
SELECT #cols = coalesce(#cols + ',','') + '[' + CostCenterNumber + ']' FROM #MyTable
SET #sql =
'SELECT Year, GLClass, Code, GLDescription, ' + #cols + '
FROM (
SELECT *
FROM #MyTable
) as P
PIVOT
(
SUM(Total)FOR [CostCenterNumber] IN (' + #cols + ')
)AS pvt'
EXEC(#sql)
I suggest you to use where and between condition from your query