SQL dynamic pivot for multiple columns - sql-server

DECLARE #cols AS NVARCHAR(MAX),
#query AS NVARCHAR(MAX)
select #cols = STUFF((SELECT ',' + QUOTENAME(Symbol)
from Opt
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set #query = 'SELECT Date,' + #cols + ' from
(
select Date, Symbol, Price
from Opt
)x
pivot
(
max(Price)
for Symbol in (' + #cols + ')
) p'
execute(#query);
I get this from the above code:
Symbols(varchar50) Date price quantity
apple 14/11/2016 30 15
banana 14/11/2016 22 20
i need like this
Date apple_price apple_quantity banana_price banana_quantity
14/11/2016 30 15 22 10
from above code i get only price

Just a minor twist to your original. Notice the sub-query/Union All.
Declare #SQL varchar(max)
Select #SQL = Stuff((Select Distinct
',' + QuoteName(Symbol+'_Price')
+ ',' + QuoteName(Symbol+'_Quantity')
From Opt For XML Path('')),1,1,'')
Select #SQL = 'Select Date,' + #SQL + '
From (
Select Date,Item=Symbol+''_Price'',Val=Price From Opt
Union All
Select Date,Item=Symbol+''_Quantity'',Val=Quantity From Opt
) A
Pivot (max(Val) For Item in (' + #SQL + ') ) p'
Exec(#SQL);
Returns
Date apple_Price apple_Quantity banana_Price banana_Quantity
2016-11-14 30 15 22 20

Related

Get the column's data in procedure? [duplicate]

I have the following data output from my database
Observation 1 aug -2015
Improvement suggestion 1 dec -2015
Observation 1 dec -2015
Accident 2 jan -2016
Non Conformity 5 jan -2016
Observation 5 jan -2016
I've tried to figure out how to use PIVOT-table to make this work but cannot make it work. The date is dynamic depending on a date in the database. The output I am looking for is like below. Can someone please point me into right direction?
Look at the fiddle what I've tried so far I know it is using SUM right now, and that is not correct, but I cannot figure out what to use. http://sqlfiddle.com/#!3/0bd0c/4
PS. The data and the image are not related, so don't be fooled by the image. It is just an example
Is this what you were looking for:
DECLARE #cols AS NVARCHAR(MAX),
#query AS NVARCHAR(MAX)
select #cols = STUFF((SELECT DISTINCT ',' + QUOTENAME(ColumnName)
from tempData
group by ColumnName, name
FOR XML PATH(''), Type
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set #query = N'SELECT Name, ' + #cols + N' from
(
select Name, value, ColumnName
from tempData
) x
pivot
(
SUM(value)
for ColumnName in (' + #cols + N')
) p '
exec sp_executesql #query;
Changing this in your fiddle return the rows as you need it.
Try it like this:
DECLARE #cols AS NVARCHAR(MAX)=
STUFF(
(
SELECT DISTINCT ',[' + ColumnName + ']'
FROM tempData
FOR XML PATH('')
)
,1,1,'');
DECLARE #SqlCmd VARCHAR(MAX)=
'SELECT p.*
FROM
(
SELECT *
FROM tempData
) AS tbl
PIVOT
(
SUM(Value) FOR ColumnName IN(' + #cols +')
) AS p';
EXEC(#SqlCmd);

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;

Create indexed view from defined pivot table

I have a requirement of creating a view for pivot table
This is my source table
According to my requirement I have created the following pivot table
DECLARE #cols AS NVARCHAR(MAX), #query AS NVARCHAR(MAX)
select #cols = STUFF((SELECT ',' + QUOTENAME(Date)
from Salse_Data
group by Date
order by Date
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set #query = 'SELECT Product,' + #cols + ' from
(
select Product, Date, Salse
from Salse_Data
) x
pivot
(
sum(Salse)
for Date in (' + #cols + ')
) p '
execute(#query);
Output is
I need to create an indexed view(Materialized View) above query
So i used procedure to create the view
CREATE PROCEDURE [dbo].[ProductSalse_By_Year_Proc_4]
AS
BEGIN
DECLARE #cols AS NVARCHAR(MAX), #query AS NVARCHAR(MAX)
select #cols = STUFF((SELECT ',' + QUOTENAME(Date)
from Salse_Data
group by Date
order by Date
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set #query = 'CREATE VIEW abcd with schemabinding as SELECT Product,' + #cols + ' from
(
select Product, Date, Salse
from Salse_Data
) x
pivot
(
sum(Salse)
for Date in (' + #cols + ')
) p '
EXECUTE(#query)
END
GO
this execuce without errors but not created the view.
Could you please help on this issue?

T sql CONCAT by comma dynamic query

I have dynamic sql query as below.
DECLARE #cols AS NVARCHAR(MAX) = '[0],[3],[11]',
#query AS NVARCHAR(MAX)
SET #query = N'SELECT * FROM
(
SELECT
year(createdDate) as [year],month(createdDate) as [month],cp.product_Id as product_ID,cp.salesprice as Amount
FROM customer_products cp
)s
PIVOT
(
SUM(Amount)
FOR product_Id IN ( '+ #cols +' ))
AS pvt;'
EXECUTE(#query)
Question:
Above query works however below query is not working because of
SELECT #cols = CONCAT(#cols, '[', cast(product_ID as varchar),']') FROM Product
code block.Error displays Incorrect syntax near
DECLARE #cols AS NVARCHAR(MAX) = '',
#query AS NVARCHAR(MAX)
SELECT #cols = CONCAT(#cols, '[', cast(product_ID as varchar),'],') FROM Product
SET #query = N'SELECT * FROM
(
SELECT
year(createdDate) as [year],month(createdDate) as [month],cp.product_Id as product_ID,cp.salesprice as Amount
FROM customer_products cp
)s
PIVOT
(
SUM(Amount)
FOR product_Id IN ( '+ #cols +' ))
AS pvt;'
EXECUTE(#query)
Where i miss exactly what is missing in above query while selecting productID from Product ?
You need to remove last , from #cols, add
SET #cols = LEFT(#cols, LEN(#cols) - 1)
You can consider using XML instead CONCAT like:
SELECT #cols = STUFF((SELECT ',' + QUOTENAME(CAST(product_ID as VARCHAR(10)))
FROM Products
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
, 1, 1, '');
It is a good practice to define length for cast(product_ID as varchar(10))
You need to ensure the last comma is removed from the select list, or you're passing an empty value to PIVOT.
Use this:
DECLARE #cols AS NVARCHAR(MAX) = '',
#query AS NVARCHAR(MAX)
SELECT #cols = COALESCE(#cols+', ','') + '[' + cast(product_ID as varchar) + ']' FROM product
SET #query = N'SELECT * FROM
(
SELECT
year(createdDate) as [year],month(createdDate) as [month],cp.product_Id as product_ID,cp.salesprice as Amount
FROM customer_products cp
)s
PIVOT
(
SUM(Amount)
FOR product_Id IN ( '+ #cols +' ))
AS pvt;'
EXECUTE(#query)

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