Returning "0" for NULL values within Dynamic Pivot for SQL Server - sql

I have the following Code:
DECLARE #cols AS NVARCHAR(MAX),
#query AS NVARCHAR(MAX)
SET #cols = STUFF((SELECT distinct ',' + QUOTENAME(month)
from PRCombinedRM
group by month,AccountNumber
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set #query = 'SELECT AccountNumber,' + 'FullName,' + 'AccountType,' + 'Company,' + 'AccountBalance,' + #cols + ' from
(
select AccountNumber,
FullName,
AccountType,
Company,
AccountBalance,
month,
amount
from PRCombinedRM
) x
pivot
(
sum(amount)
for month in (' + #cols + ')
) p '
execute(#query)
However currently the results that this is outputting shows the values for "amount" as a NULL, however I would like to replace the NULL values with "0" instead.
How would I go about doing this?
Currently the data outputs as such:
AccountNumber FullName AccountType Company AccountBalance Aug Jul Jun Sep
100 M R Test Test Account Test Company 100 -50 -50 NULL -50
However I would like the data to output as:
AccountNumber FullName AccountType Company AccountBalance Aug Jul Jun Sep
100 M R Test Test Account Test Company 100 -50 -50 0 -50
Thank you.

I would use another variable to store the ISNULL(someColumn,0):
DECLARE #cols AS NVARCHAR(MAX), #query AS NVARCHAR(MAX);
DECLARE #cols2 AS NVARCHAR(MAX)
SET #cols = STUFF((SELECT distinct ',' + QUOTENAME(month)
from PRCombinedRM
group by month,AccountNumber
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'');
SET #cols2 = STUFF((SELECT distinct ', ISNULL(' + QUOTENAME(month) + ',0) ' + QUOTENAME(month)
from PRCombinedRM
group by month,AccountNumber
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'');
set #query = 'SELECT AccountNumber,' + 'FullName,' + 'AccountType,' + 'Company,' + 'AccountBalance,' + #cols2 + ' from
(
select AccountNumber,
FullName,
AccountType,
Company,
AccountBalance,
month,
Amount
from PRCombinedRM
) x
pivot
(
sum(amount)
for month in (' + #cols + ')
) p ';
execute(#query);

You can change the #cols definition:
SET #cols = STUFF((SELECT distinct ', coalesce(' + QUOTENAME(month) ', 0) as ' + QUOTENAME(month)
from PRCombinedRM
group by month,AccountNumber
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
, 1, 2,'')

Related

How to arrange the columns of an SQL pivot table in ascending order

Can someone help me in arranging the columns in ascending order.
My output of pivot table is like:
Ref role_name offer_id 10000 104000 8000 8400
43132_43282 Call Center 1 1 0 0 6
43132_43282 Others 1 2 0 0 3
Instead I want it to be like:
Ref role_name offer_id 8000 8400 10000 104000
43132_43282 Call Center 1 0 6 1 0
43132_43282 Others 1 0 3 2 0
DECLARE #cols AS NVARCHAR(MAX), -- for pivot
#cols2 AS NVARCHAR(MAX), -- for select
#query AS NVARCHAR(MAX);
SET #cols = STUFF((
SELECT DISTINCT ',' + QUOTENAME(c.[Offer_cover])
FROM #cover2 c
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)'), 1, 1, '')
-- this is for the SELECT
SET #cols2 = STUFF((
SELECT DISTINCT ',' + 'ISNULL(' + QUOTENAME(c.[Offer_cover]) + ', 0) ' + QUOTENAME(c.[Offer_cover])
FROM #cover2 c
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)'), 1, 1, '')
SET #query = 'SELECT Ref,role_name,offer_id, ' + #cols2 + ' from
(
select *
from #cover2
) x
pivot
(
SUM(cover_earning_Count)
for [Offer_cover] in (' + #cols + ')
) p'
EXECUTE (#query)
Can you add the GROUP BY, ORDER BY [Offer_cover] in the #cols2 variable selection and remove the DISTINCT.
So the query will be:
SET #cols2 = STUFF((
SELECT ',' + 'ISNULL(' + QUOTENAME(c.[Offer_cover]) + ', 0) ' + QUOTENAME(c.[Offer_cover])
FROM #cover2 c
GROUP BY c.[Offer_cover] -- changes here
ORDER BY c.[Offer_cover] -- changes here
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)'), 1, 1, '')
it will return the #cols2 in the ascending order, so it will impact in the final result.

Sql Pivoting on date

I am getting this error when trying to convert the below logic in to SQL query
Logic:
TRANSFORM First([SirName] & " - " & [SecondName]) AS Name
SELECT qry_Date.RoomNumber
FROM Guest RIGHT JOIN qry_Date ON Guest.ID = qry_Date.GuestID
WHERE (((qry_Date.RoomNumber) Is Not Null))
GROUP BY qry_Date.RoomNumber
PIVOT qry_Date.Date;
Below is what i have done so far
DECLARE #cols AS NVARCHAR(MAX)
DECLARE #query AS VARCHAR(MAX)
SELECT #cols = STUFF((SELECT distinct top 100 percent
',' + QUOTENAME(convert(NVARCHAR(MAX),qry_Date.Date,103))
FROM qry_Date
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)'),1,1,'');
SET #query = 'SELECT Name, ' + #cols + '
FROM
(SELECT [SirName] + '' - '' + [SecondName] AS Name
,qry_Date.RoomNumber
,qry_Date.Date
FROM Guest RIGHT JOIN qry_DateTemp ON Guest.ID = qry_Date.GuestID
WHERE qry_Date.RoomNumber Is Not Null) as t
PIVOT
(count(Name) FOR [Date] IN( ' + #cols + ')
) as p'
print #query
execute(#query)
Which results error
Msg 8114, Level 16, State 1, Line 9 Error converting data type
nvarchar to datetime2. Msg 473, Level 16, State 1, Line 9 The
incorrect value "13/12/2014" is supplied in the PIVOT operator. Msg
207, Level 16, State 1, Line 1 Invalid column name 'Name'.
My print #query output
SELECT Name, [01/12/2014],[02/12/2014],[03/12/2014],[04/12/2014],[05/12/2014],[06/12/2014],[07/12/2014],[08/12/2014],[09/12/2014],[10/12/2014],[11/12/2014],[12/12/2014],[13/12/2014],[14/12/2014],[15/12/2014],[16/12/2014],[17/12/2014],[18/12/2014],[19/12/2014],[20/12/2014],[21/12/2014],[22/12/2014],[23/12/2014],[24/12/2014],[25/12/2014],[26/12/2014],[27/12/2014],[28/12/2014],[29/12/2014],[30/12/2014],[31/12/2014]
FROM
(SELECT [SirName] + '' - '' + [SecondName] AS Name
,qry_Date.RoomNumber
,qry_Date.Date
FROM Guest RIGHT JOIN qry_Date ON Guest.ID = qry_Date.GuestID
WHERE qry_Date.RoomNumber Is Not Null) as t
PIVOT
(count(Name) FOR [Date] IN( [01/12/2014],[02/12/2014],[03/12/2014],[04/12/2014],[05/12/2014],[06/12/2014],[07/12/2014],[08/12/2014],[09/12/2014],[10/12/2014],[11/12/2014],[12/12/2014],[13/12/2014],[14/12/2014],[15/12/2014],[16/12/2014],[17/12/2014],[18/12/2014],[19/12/2014],[20/12/2014],[21/12/2014],[22/12/2014],[23/12/2014],[24/12/2014],[25/12/2014],[26/12/2014],[27/12/2014],[28/12/2014],[29/12/2014],[30/12/2014],[31/12/2014])
) as p
One quick way to deal with this error is to convert all data to varchar(max) in same manner. After all dates will become header, so it should be string.
DECLARE #cols AS NVARCHAR(MAX)
DECLARE #query AS VARCHAR(MAX)
SELECT #cols = STUFF((SELECT distinct top 100 percent
',' + QUOTENAME(CAST(qry_Date.Date AS NVARCHAR(MAX)))
FROM qry_Date
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)'),1,1,'');
SET #query = 'SELECT RoomNumber, ' + #cols + '
FROM
(SELECT [SirName] + '' - '' + [SecondName] AS Name
,qry_Date.RoomNumber
,CAST(qry_Date.Date AS NVARCHAR(MAX)) as [Date]
FROM Guest RIGHT JOIN qry_DateTemp ON Guest.ID = qry_Date.GuestID
WHERE qry_Date.RoomNumber Is Not Null) as t
PIVOT
(count(Name) FOR [Date] IN( ' + #cols + ')
) as p'
print #query
execute(#query)
#DhruvJoshi did it as u Proposed and true i was in error. when i got my results i had to change the query to
DECLARE #cols AS NVARCHAR(MAX)
DECLARE #query AS VARCHAR(MAX)
SELECT #cols = STUFF((SELECT distinct top 100 percent
',' + QUOTENAME(CAST(qry_Date.Date AS NVARCHAR(MAX)))
FROM qry_Date
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)'),1,1,'');
SET #query = 'SELECT RoomNumber, ' + #cols + '
FROM
(SELECT [SirName] + '' - '' + [SecondName] AS Names
,qry_Date.RoomNumber
,CAST(qry_Date.Date AS NVARCHAR(MAX)) as [Date]
FROM Guest RIGHT JOIN qry_Date ON Guest.ID = qry_Date.GuestID
WHERE qry_Date.RoomNumber Is Not Null) as t
PIVOT
(MAX([Names]) FOR [Date] IN( ' + #cols + ')
) as p'
print #query
execute(#query)

Generating expression string in SQL to add values of a column in pivot

I want to get this string for using in my other queries
#cols = 'ISNULL(myColumnName_value_1,0) + ISNULL(myColumnName_value_2,0) + ... + ISNULL(myColumnName_value_N,0)'
and myColumnName_value_1 ORmyColumnName_value_2 , ... which could be anything.
And my query is:
DECLARE #cols AS NVARCHAR(MAX)
SET #cols = STUFF((SELECT distinct ' + ISNULL(' + (c.myColumnName) +',0)'
FROM myTableName c
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
print #cols
but I can't get what I want.
my desired output of print:
ISNULL(myColumnName_value_1,0) +
ISNULL(myColumnName_value_2,0) + ... +
ISNULL(myColumnName_value_N,0)
And ... because I don't know the name or number of columns.
Here is your modified query.
DECLARE #cols AS NVARCHAR(MAX)
SET #cols = STUFF((SELECT distinct ' + ISNULL(' + QUOTENAME(c.myColumnName) +',0)'
FROM myTableName c
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,2,1,'')
print #cols

Sort Rows of Dynamic Pivot Table

I have the following query to dynamically pivot some row information:
DECLARE #cols AS NVARCHAR(MAX),
#query AS NVARCHAR(MAX);
select #cols = STUFF((SELECT ',' + QUOTENAME(convert(char(50), ScheduleEndTime, 120))
FROM metersNotRead
group by ScheduleEndTime
order by ScheduleEndTime DESC
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set #query = 'SELECT ScheduleName, MeterID, CurrentGK,
' + #cols + ' from
(
select ScheduleName, MeterID, CurrentGK, ScheduleEndTime, ''Y'' flag
from metersNotRead
) x
pivot
(
max(flag)
for ScheduleEndTime in (' + #cols + ')
) p
order by ' + #cols +' DESC
'
execute(#query)
It gives me the correct results, but I am wondering how I can sort the rows by the first dynamic column, then the second, and so on, until all dynamic columns have been ordered by.
The results I have now are like this:
ScheduleName MeterID CurrentGK FirstDynamicCol SecondDynamicCol ETC
textName1 exampleID1 -- NULL Y
taxtName2 exampleID2 -- Y NULL
I want them to be like this:
ScheduleName MeterID CurrentGK FirstDynamicCol SecondDynamicCol ETC
textName2 exampleID2 -- Y NULL
taxtName1 exampleID1 -- NULL Y
Try this, put your first column name in its own variable, and order by that only.
DECLARE #cols AS NVARCHAR(MAX), #orderby NVARCHAR(MAX),
#query AS NVARCHAR(MAX);
select #orderby = STUFF((SELECT ',' + QUOTENAME(convert(char(50), ScheduleEndTime, 120)) + ' desc'
FROM metersNotRead
group by ScheduleEndTime
order by ScheduleEndTime DESC
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
select #cols = STUFF((SELECT ',' + QUOTENAME(convert(char(50), ScheduleEndTime, 120))
FROM metersNotRead
group by ScheduleEndTime
order by ScheduleEndTime DESC
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set #query = 'SELECT ScheduleName, MeterID, CurrentGK,
' + #cols + ' from
(
select ScheduleName, MeterID, CurrentGK, ScheduleEndTime, ''Y'' flag
from metersNotRead
) x
pivot
(
max(flag)
for ScheduleEndTime in (' + #cols + ')
) p
order by ' + #orderby
execute(#query)

Dynamic Pivot Results to a Temp Table

While I was able to find how to pivot this data in these forums, I have not been able to find a means to push the results to a temp table so that I can use it for other queries. The code is the following. Is there a possible way to have the output of this populate a temp table?
SET #cols = STUFF((SELECT distinct ',' + QUOTENAME(QT.QUESTION_DESC)
FROM #QUES_TEMP QT
GROUP BY QT.QUESTION_DESC
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set #query = 'SELECT EVAL_ID, AuditType, ' + #cols + '
into ##tmp
from
(
select QT.EVAL_ID,
QT.AuditType,
QT.SCORE,
QT.QUESTION_DESC
from #QUES_TEMP QT
) x
pivot
(
max(SCORE)
for QUESTION_DESC in (' + #cols + ')
) p '
execute(#query);
select * from ##tmp
You should be able to use INTO Clause. I added INTO into your example.
SET #cols = STUFF((SELECT distinct ',' + QUOTENAME(QT.QUESTION_DESC)
FROM #QUES_TEMP QT
GROUP BY QT.QUESTION_DESC
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set #query = 'SELECT EVAL_ID, AuditType, ' + #cols + ' from
(
select QT.EVAL_ID,
QT.AuditType,
QT.SCORE,
QT.QUESTION_DESC
into ##tmp
from #QUES_TEMP QT
) x
pivot
(
max(SCORE)
for QUESTION_DESC in (' + #cols + ')
) p '
execute(#query);
SELECT * FROM ##tmp
SET #cols = STUFF((SELECT distinct ',' + QUOTENAME(QT.QUESTION_DESC)
FROM #QUES_TEMP QT
GROUP BY QT.QUESTION_DESC
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set #query = 'SELECT EVAL_ID, AuditType, ' + #cols + '
from
(
select QT.EVAL_ID,
QT.AuditType,
QT.SCORE,
QT.QUESTION_DESC
from #QUES_TEMP QT
) x
pivot
(
max(SCORE)
for QUESTION_DESC in (' + #cols + ')
) p '
set #query = 'select * into ##Temp from ('+#query+') y'
execute(#query)
select * from ##Temp