Convert row into column when number of row is not fixed - sql-server

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;

Related

Copy oldtable to newTable base on pivot query result?

I have a pivot query from pivoted table*(a dynamic columns)*, my problem is I want to copy/clone the pivot result into new_table. Which is I don't know how to do it,
Query:
DECLARE #cols NVARCHAR(MAX), #query NVARCHAR(MAX);
SET #cols = STUFF((SELECT DISTINCT','+QUOTENAME(c.ReportedDate)
FROM dbo.Activity c FOR XML PATH(''), TYPE).value('.', 'nvarchar(max)'), 1, 1, '');
SELECT #query = 'SELECT * FROM (SELECT b.Description, CONVERT(VARCHAR(10), reportedDate, 120) as reportedDate,Status
FROM Activity left join ActivityType b on b.activityTypeId = Activity.ActivityTypeId )
AS t PIVOT ( COUNT(reportedDate) FOR reportedDate IN( ' + #cols + ' )' + ') AS p ;'
EXECUTE (#query);
How to achieve my expectations to get the same result from pivotTable to new_table with the same data result?
You can use a table (or a global temporary table) to store data via select into, so you will able to have access on it.
DECLARE #cols NVARCHAR(MAX), #query NVARCHAR(MAX);
SET #cols = STUFF((SELECT DISTINCT','+QUOTENAME(c.ReportedDate)
FROM dbo.Activity c FOR XML PATH(''), TYPE).value('.', 'nvarchar(max)'), 1, 1, '');
SELECT #query = 'SELECT * into ##results FROM (SELECT b.Description, CONVERT(VARCHAR(10), reportedDate, 120) as reportedDate,Status
FROM Activity left join ActivityType b on b.activityTypeId = Activity.ActivityTypeId )
AS t PIVOT ( COUNT(reportedDate) FOR reportedDate IN( ' + #cols + ' )' + ') AS p ;'
EXECUTE (#query);
SELECT * FROM ##results

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)

Generate dynamic columns using pivot

I have the following query which is always giving the error. Could some body help me
to resolve this?
"Incorrect syntax near the keyword '#stqsql'".
My code is:
declare #strsql nvarchar(max)
set #strsql=select merchantid from employee
select *
from
(
Select s.employeeid,
COUNT(*) as TotCount
from Employee s
GROUP BY s.employeeid
)as a
pivot (avg(TotCount) for employeeid IN ('+#stqsql+')) AS NoOfRec
Unfortunately the way you are trying to get dynamic columns does not work. You will have to use something similar to the following:
DECLARE #colsPivot AS NVARCHAR(MAX),
#query AS NVARCHAR(MAX)
-- this gets the list of values that you want to pivot
select #colsPivot = STUFF((SELECT distinct ', ' + QUOTENAME(merchantid )
from employee
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
-- since you are use a dynamic list you have to use dynamic sql
set #query = 'SELECT ' + #colsPivot + ' from
(
SELECT s.employeeid,
COUNT(*) as TotCount
FROM Employee s
GROUP BY s.employeeid
) src
pivot
(
avg(TotCount)
for employeeid in (' + #colsPivot + ')
) p '
execute(#query)

Resources