Dynamic pivot - Incorrect syntax error near #cols - sql-server

I have a view in Sql Server called 'ITEMS_PRICE'.
Some of it's columns are the 'Name' column and 'FormulaResult_Cost' column.
What I am trying to do, is using dynamic pivot, make all rows of 'Name' field as columns and take as value, the value of 'FormulaResult_Cost'.
Here is my SQL Query:
DECLARE #query NVARCHAR(4000)
DECLARE #cols NVARCHAR(4000)
SELECT #cols = STUFF((SELECT distinct '' + QUOTENAME(p.Name)
from ITEMS_PRICE AS p
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)') ,1,0,'')
--select STUFF(#cols, 1,0,'')
set #query = 'SELECT p.ItemCode, p.ItemName, p.ItmsGrpCod, p.ItmsGrpNam, p.Name, p.FormulaResult_Cost, ' + #cols + '
from
ITEMS_PRICE as p
pivot
(
max(p.FormulaResult_Cost)
for p.Name in (' + '[' #cols + ']' + ')
) AS t'
EXECUTE(#query)
The error that I get is:
Msg 102, Level 15, State 1, Line 29 Incorrect syntax near '#cols'.
Also, I don't want the dynamic pivot to have any aggregate functions. I just read in some forums that you have to use, at least max() function in order to be correct the for ... in code.

You're missing a + before #cols on this line: for p.Name in (' + '[' #cols + ']' + ') should be for p.Name in (' + '[' + #cols + ']' + ').
But I don't believe you need the extra square brackets in there, as the QUOTENAME method will add them, so it should read:
for p.Name in (' + #cols + ')
Also, if you're doing for p.Name in (#cols), your STUFF function should return comma separated values, so I would update your declaration to to include a comma after the distinct:
SELECT #cols = STUFF((SELECT distinct ',' + QUOTENAME(p.Name)
from ITEMS_PRICE AS p
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)') ,1,0,'')
Full query:
DECLARE #query NVARCHAR(4000)
DECLARE #cols NVARCHAR(4000)
SELECT #cols = STUFF((SELECT distinct ',' + QUOTENAME(p.Name)
from ITEMS_PRICE AS p
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)') ,1,0,'')
--select STUFF(#cols, 1,0,'')
set #query = 'SELECT p.ItemCode, p.ItemName, p.ItmsGrpCod, p.ItmsGrpNam,
p.Name, p.FormulaResult_Cost, ' + #cols + '
from
ITEMS_PRICE as p
pivot
(
max(p.FormulaResult_Cost)
for p.Name in (' + #cols + ')
) AS t'
EXECUTE(#query)

Add + before #cols. ('[' #cols + ']')
set #query = 'SELECT p.ItemCode, p.ItemName, p.ItmsGrpCod,
p.ItmsGrpNam, p.Name, p.FormulaResult_Cost, ' + #cols + '
FROM
ITEMS_PRICE as p
pivot
(
max(p.FormulaResult_Cost)
for p.Name in (''' + #cols + ''')
) AS t'

Related

How do I create a new table from the results of a dynamic SQL statement in T-SQL

I'm trying to use the results from this dynamic SQL statement, to create a new table
DECLARE #cols NVARCHAR(MAX), #query NVARCHAR(MAX);
SET #cols = STUFF((SELECT DISTINCT
',' + QUOTENAME(c.[ClassCode])
FROM [Sandbox].[dbo].Test2 c
FOR XML PATH(''), TYPE).value('.', 'nvarchar(max)'), 1, 1, '');
SET #query = 'SELECT [Name_ID], ' + #cols +
'FROM (SELECT [Name_ID],
[ClassCodeYN] AS [amount],
[ClassCode] AS [category]
FROM [Sandbox].[dbo].[Test2]) x
PIVOT (COUNT(amount) FOR category IN (' + #cols + ')) p';
EXECUTE #query
I've tried to use INSERT INTO and CREATE TABLE and get either
Incorrect syntax near the keyword 'EXECUTE'
or
Must DECLARE #query
errors.
You should be able to just add into <table> to your existing query:
DECLARE #cols NVARCHAR(MAX), #query NVARCHAR(MAX);
SET #cols = STUFF((SELECT DISTINCT
',' + QUOTENAME(c.[ClassCode])
FROM [Sandbox].[dbo].Test2 c
FOR XML PATH(''), TYPE).value('.', 'nvarchar(max)'), 1, 1, '');
SET #query = 'SELECT [Name_ID], ' + #cols +
' INTO MyTable' +
' FROM (SELECT [Name_ID],
[ClassCodeYN] AS [amount],
[ClassCode] AS [category]
FROM [Sandbox].[dbo].[Test2]) x
PIVOT (COUNT(amount) FOR category IN (' + #cols + ')) p';
Exec sp_executesql #query

Convert row into column when number of row is not fixed

I want to convert Row into column as shown in below Expected result image.
I have a table and getting data as shown Existing Table image.
Designation Column has dynamic value(Number of value is not fix)
I tried:
DECLARE #cols AS NVARCHAR(MAX),#query AS NVARCHAR(MAX)
select #cols = STUFF((SELECT ',' + QUOTENAME(designation)
from MyTable
group by designation
order by designation
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)'),1,1,'')
set #query = N'SELECT ' + #cols + N' from
(
select SanctionStrength , designation from MyTable
) x
pivot
(
max(SanctionStrength) for designation in (' + #cols + N')
) p '
exec sp_executesql #query;
I am getting result as expected but only for SS.
How can i bind value of AS and VAC together.
you need to combine columns before pivot.
DECLARE #cols AS NVARCHAR(MAX),#query AS NVARCHAR(MAX)
select #cols = STUFF((SELECT ',' + QUOTENAME(designation)
from MyTable
group by designation
order by designation
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)'),1,1,'')
set #query = N'SELECT Row, ' + #cols + N' from
(
select ''SS'' Row, SS AS Value , designation from MyTable
UNION ALL
select ''AS'' Row, [AS] AS Value , designation from MyTable
UNION ALL
select ''Vac'' Row, Vac AS Value , designation from MyTable
) x
pivot
(
max(Value) for designation in (' + #cols + N')
) p '
exec sp_executesql #query;

SQL - Columns are not alphabetic

Columns are not alphabetic because I can't use "order by" with "distinct".Please help me...
My Query :
DECLARE #cols AS NVARCHAR(MAX),
#query AS NVARCHAR(MAX);
SET #cols = STUFF((SELECT distinct ',MAX(CASE WHEN KullaniciAdi = ''' + p.KullaniciAdi + ''' THEN KisiAdi END) AS ' + QUOTENAME(p.KullaniciAdi)
FROM Populer p FOR XML PATH(''), TYPE ).value('.', 'NVARCHAR(MAX)') ,1,1,'')
set #query = 'SELECT top 100 ' + #cols + ' FROM ( SELECT KullaniciAdi,KisiAdi,ROW_NUMBER() OVER (PARTITION BY KullaniciAdi ORDER BY EklenmeTarihi) AS RowNum FROM Populer ) x GROUP BY RowNum '
EXECUTE(#query)
Results:
Of course you can. The key is to replace the distinct with group by. Then use order by:
SET #cols = STUFF((SELECT ', MAX(CASE WHEN KullaniciAdi = ''' + p.KullaniciAdi + ''' THEN KisiAdi END) AS ' + QUOTENAME(p.KullaniciAdi)
FROM Populer p
GROUP BY KullaniciAdi
ORDER BY p.KullaniciAdi
FOR XML PATH(''), TYPE ).value('.', 'NVARCHAR(MAX)'
), 1, 1, ''
) ;
One way around this is to make your query a derived table:
SELECT * FROM
(SELECT DISTINCT {the rest of your current query}) t
ORDER BY SomeColumn

How to use where statement in a dynamic column

i need to make a 'where' statement in a dynamic column.
the dynamic column came from a row item.
sample as below.
SET #paramList = STUFF((
SELECT DISTINCT ',[' + parameter + ']'
FROM #tblitems FOR XML PATH('')
)
,1,1,'')
#paramList = [item1],[item2],[item3]
using the below query i need to incorporate the where statement at the end. but the column from the #paramlist should all be equal to 1 only.
SET #query ='select no,
' + #paramList + '
FROM( SELECT * FROM #tblitems)src
PIVOT
(
max(value)
for [parameter] in (' + #paramList + ')
) as piv order by item'
Create the condition string in the same way as the column list:
SET #condition = STUFF((
SELECT DISTINCT ' AND [' + parameter + '] = 1'
FROM #tblitems FOR XML PATH('')
)
,1,5,'');
Note though that you can also use the QUOTENAME function instead of enclosing the name in square brackets manually:
SET #condition = STUFF((
SELECT DISTINCT ' AND ' + QUOTENAME(parameter) + ' = 1'
FROM #tblitems FOR XML PATH('')
)
,1,5,'');
Now that you've got the condition string, you can add it to the dynamic query:
SET #query ='SELECT no,
' + #paramList + '
FROM (SELECT * FROM #tblitems) AS src
PIVOT
(
MAX(value)
FOR [parameter] IN (' + #paramList + ')
) AS piv
WHERE ' + #conditions + '
ORDER BY item;';

How to filter pivot results

Is it possible to exclude some vaules from the PIVOT results.
Referencing this question i would like to know if it is posible to exclude the columns in the Pivot table that has 0 value.
Imagine there is a count of 0 for EventType Meeting, is it possible not to show it at all?
i hope you have implemented following solution from the question
DECLARE #cols AS NVARCHAR(MAX),
#query AS NVARCHAR(MAX)
select #cols = STUFF((SELECT distinct ',' + QUOTENAME(EventType)
from dbo.testTable
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set #query = 'SELECT year,' + #cols + '
from
(
select EventType,
year = year(date)
from dbo.testTable
) x
pivot
(
count(EventType)
for EventType in (' + #cols + ')
) p '
execute(#query)
if so then you can do following
DECLARE #cols AS NVARCHAR(MAX),
#where AS NVARCHAR(MAX),
#query AS NVARCHAR(MAX)
select #cols = STUFF((SELECT distinct ',' + QUOTENAME(EventType)
from dbo.testTable
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
select #where = ' where ' + STUFF((SELECT distinct ' Or ' + QUOTENAME(EventType) + ' <> 0 '
from dbo.testTable
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,2,3,'')
set #query = 'SELECT year,' + #cols + '
from
(
select EventType,
year = year(date)
from dbo.testTable
) x
pivot
(
count(EventType)
for EventType in (' + #cols + ')
) p ' + #where
execute(#query)

Resources