i have a pivot table that display student absence, there is not problem in executing and the result of the pivot but if there is no value it display null, i want to display 0 not a null. i googled and found some ways i try use them but i can't do it. can anyone tell me please?
this my pivot table code:
create proc [dbo].[get_st_abs_by_stage]
#Stage_ID smallint
as
CREATE TABLE #SummaryTable
(
SName nvarchar(50),
CName nvarchar(50),
Stage_ID SmallInt,
Sum_Abs SmallInt
)
delete from #SummaryTable
INSERT INTO #SummaryTable(SName, CName, Stage_ID, Sum_Abs)
SELECT Student_tbl.SName,Courses_tbl.CName,Stages_tbl.Stage_ID,Sum_Abs from Absence_Summary_tbl
inner join Student_tbl on Student_tbl.S_ID = Absence_Summary_tbl.S_ID
inner join Stages_tbl on Stages_tbl.Stage_ID = Student_tbl.Stage_ID
inner join Courses_tbl on Courses_tbl.C_ID = Absence_Summary_tbl.C_ID
where Stages_tbl.Stage_ID = #Stage_ID;
DECLARE #cols AS NVARCHAR(MAX),
#query AS NVARCHAR(MAX)
select #cols = STUFF((SELECT ',' + QUOTENAME(CName)
from #SummaryTable
where Stage_ID = #Stage_ID
group by CName
order by CName
FOR XML PATH(''), TYPE ).value('.', 'NVARCHAR(MAX)') ,1,1,'')
set #query = 'SELECT SName,' + #cols + ' from
(
select SName, CName, Sum_Abs
from #SummaryTable
) x
pivot
(
sum(Sum_Abs)
for CName in (' + #cols + ')
) p '
execute(#query);
You can generate another variable with isnull for cols. Something like this
select #cols = STUFF((SELECT ',' + QUOTENAME(CName)
from #SummaryTable
where Stage_ID = #Stage_ID
group by CName
order by CName
FOR XML PATH(''), TYPE ).value('.', 'NVARCHAR(MAX)') ,1,1,'')
select #isnull_cols = STUFF((SELECT ', isnull(' + QUOTENAME(CName) + ', 0) as ' + QUOTENAME(CName)
from #SummaryTable
where Stage_ID = #Stage_ID
group by CName
order by CName
FOR XML PATH(''), TYPE ).value('.', 'NVARCHAR(MAX)') ,1,1,'')
set #query = 'SELECT SName,' + #isnull_cols + ' from
(
select SName, CName, Sum_Abs
from #SummaryTable
) x
pivot
(
sum(Sum_Abs)
for CName in (' + #cols + ')
) p '
execute(#query);
Related
I am working on an example to write dynamic sql to pivot the data in ssis expression builder.It fails to evaluate the expression. Below is the dynamic query:
DECLARE #Cols as NVARCHAR(MAX)
DECLARE #SQL as NVARCHAR(MAX)
SELECT #Cols = COALESCE(#Cols + ', ','') + QUOTENAME(Name)
FROM
(
SELECT DISTINCT Category
FROM Product
) As t1
SET #SQL = 'SELECT *
FROM
(
SELECT ProductID,
Category,
Quantity
FROM Product
) as PivotData
PIVOT
(
COUNT(Quantity)
FOR Category IN (" + #Cols + ")
) AS PivotResult'
I think your double quotes around + #Cols needs to be single quotes, see below.
DECLARE #Cols as NVARCHAR(MAX)
DECLARE #SQL as NVARCHAR(MAX)
SELECT #Cols = COALESCE(#Cols + ', ','') + QUOTENAME(Name)
FROM
(
SELECT DISTINCT Category
FROM Product
) As t1
SET #SQL = 'SELECT *
FROM
(
SELECT ProductID,
Category,
Quantity
FROM Product
) as PivotData
PIVOT
(
COUNT(Quantity)
FOR Category IN (' + #Cols + ')
) AS PivotResult'
I am using this simple code to pivot some column.
But I can't make it work due to that error.
DECLARE #IO_dy AS VARCHAR(100) = '>9C604-M'
DECLARE #style_dy AS VARCHAR (100) = 'S1415MBS06'
DECLARE #query AS VARCHAR(8000)
DECLARE #con AS VARCHAR(8000)
SET #con = STUFF((SELECT distinct ',' + QUOTENAME(Size_id)
FROM iPLEXSTY_SIQ
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
SET #query = 'SELECT *
FROM (
SELECT DISTINCT a.Po_no,a.Article_id,a.Season_id,a.Customer_id,a.Destn_id,b.planned_dt, (c.Description + c.Resource_id) AS comb_size,a.Qty,a.Size_id
from iPLEXSTY_SIQ a
INNER JOIN iPLEX_BULK_PO_DET b on b.upload_batch_id = a.Batch_id
INNER JOIN iPLEXCOLORS c on c.Seq_no = a.Seq_no
WHERE IO_no = #IO_dy AND Style_id = #style_dy //ERROR HERE
GROUP BY a.Po_no,a.Article_id,a.Season_id,a.Customer_id,a.Destn_id,b.planned_dt,(c.Description + c.Resource_id),a.Qty,A.Size_id
) as s
PIVOT
(
SUM(Qty)
FOR Size_id IN (' +#con+ ')
)AS pvt'
EXEC(#query)
addition to another answer
just single quotes to the variable names used in the query
DECLARE #IO_dy AS VARCHAR(100) = '>9C604-M'
DECLARE #style_dy AS VARCHAR (100) = 'S1415MBS06'
DECLARE #query AS VARCHAR(8000)
DECLARE #con AS VARCHAR(8000)
SET #con = STUFF((SELECT distinct ',' + QUOTENAME(Size_id)
FROM iPLEXSTY_SIQ
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
SET #query = 'SELECT *
FROM (
SELECT DISTINCT a.Po_no,a.Article_id,a.Season_id,a.Customer_id,a.Destn_id,b.planned_dt, (c.Description + c.Resource_id) AS comb_size,a.Qty,a.Size_id
from iPLEXSTY_SIQ a
INNER JOIN iPLEX_BULK_PO_DET b on b.upload_batch_id = a.Batch_id
INNER JOIN iPLEXCOLORS c on c.Seq_no = a.Seq_no
WHERE IO_no = '''+#IO_dy+''' AND Style_id = '''+#style_dy+''' //ERROR HERE
GROUP BY a.Po_no,a.Article_id,a.Season_id,a.Customer_id,a.Destn_id,b.planned_dt,(c.Description + c.Resource_id),a.Qty,A.Size_id
) as s
PIVOT
(
SUM(Qty)
FOR Size_id IN (' +#con+ ')
)AS pvt'
EXEC(#query)
and also as another answer explains to set values to varchar using default keyword
You can't declare and initialize value of variable using "=". So instead of:
DECLARE #IO_dy AS VARCHAR(100) = '>9C604-M'
Use
DECLARE #IO_dy AS VARCHAR(100) DEFAULT '>9C604-M'
^^^^^^^
See this for syntax
Hi all I have written the following Procedure to display the results as pivot as per the requirement
DECLARE #values AS NVARCHAR(MAX),
#query AS NVARCHAR(MAX)
SELECT #values = STUFF(
(
SELECT DISTINCT ',[' + ColumnName + ']'
FROM xTable
FOR xml path ('')
),1,1,'')
SET #query = 'SELECT viewName1.*, pValues.Code, ' + #values + ' FROM
(
SELECT Column1,Column2, Column3
FROM viewname
) aliasName
PIVOT
(
MAX(value)
FOR ColumnName in (' + #values + ')
) pValues INNER JOIN viewName1 ON pValues.Code = viewname.Code'
EXEC(#query)
But when the value and column names are same in my xTable and viewName1 I am getting that error how can I resolve this. I tried with alas but I am not getting the expected result so can some one help me.
Sample is I am having a ColumnName as TopBrand in my table xTable, this can be a value in my viewName1 like for X Column TopBrand can be a value.
I think you need to have a separate list for FOR and IN clauses and the former should include the alias:
DECLARE #valuesFor AS NVARCHAR(MAX),
#valuesIn AS NVARCHAR(MAX),
#query AS NVARCHAR(MAX)
SELECT #valuesFor = STUFF(
(
SELECT DISTINCT N',pValues.[' + ColumnName + ']'
FROM xTable
FOR xml path ('')
),1,1,'')
SELECT #valuesIn = STUFF(
(
SELECT DISTINCT N',[' + ColumnName + ']'
FROM xTable
FOR xml path ('')
),1,1,'')
SET #query = N'SELECT viewName1.*, pValues.Code, ' + #valuesFor + N' FROM
(
SELECT Column1,Column2, Column3
FROM viewname
) aliasName
PIVOT
(
MAX(value)
FOR ColumnName in (' + #valuesIn + N')
) pValues INNER JOIN viewName1 ON pValues.Code = viewname.Code'
EXEC(#query)
I have two tables named Emp and TrainingTable
Emp columns (EmpId(PK, int, not null), EmpName(nchar(10), null))
TrainingTable columns (EmpId(FK, int, null), TainingId(int, null), TainingName(nvarchar(50), not null))
Code:
DECLARE #cols AS NVARCHAR(MAX),
#query AS NVARCHAR(MAX)
select #cols = STUFF((SELECT ',' + QUOTENAME(TainingId)
from TrainingTable
group by TainingId
order by TainingId
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set #query = 'SELECT EmpName,' + #cols + ' from
(
select Emp.EmpName, TainingName, TainingId
from TrainingTable INNER JOIN Emp ON TrainingTable.EmpId = Emp.EmpId
) x
pivot
(
max(TainingName)
for TainingId in (' + #cols + ')
) p '
execute(#query)
Now what I want to do is to rename the columns 1,2,3.. with Training1,Traning2,.. and so on..
the result table may change depending on data. columns may increase..
I tried almost every thing .. but not getting the correct way to achieve it.
Try this
You need to cast your column Using CAST()
DECLARE #cols AS NVARCHAR(MAX),
#query AS NVARCHAR(MAX)
select #cols = STUFF((SELECT ',' + QUOTENAME('Training' + CAST(TainingId AS Varchar(50)))
from TrainingTable
group by TainingId
order by TainingId
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set #query = 'SELECT EmpName,' + #cols + ' from
(
select Emp.EmpName,
TainingName,
col = ''Training'' + cast(TainingId as varchar(10))
from TrainingTable
INNER JOIN Emp ON TrainingTable.EmpId = Emp.EmpId
) x
pivot
(
max(TainingName)
for col in (' + #cols + ')
) p '
execute(#query)
Refer
I have three tables. I need to swith row values into columns.
Table-1: [Approval_Type]
App_ID Type_Ds
2 RMC2
1 RMC1
Table 2: [Project]
Pro_id Summary
1 PROJECT1
2 PROJECT2
Table:3 [Prj_App]
App_Id Pro_Id ExpDt ComDt
1 2 2010-06-05 2010-07-06
1 1 1999-05-05 1999-05-06
2 1 1900-01-01 1900-01-05
I want to display my result as
Pro_Id RMC2 RMC2ExpeDt RMC2ComDt RMC1 RMC1ExpeDt RMC1ComDt
1 RMC2 1900-01-01 1900-01-05 RMC1 1999-05-05 1999-05-06
2 NULL NULL NULL RMC1 2010-06-05 2010-07-06
Below is my query which returns'
DECLARE #SQL1 NVARCHAR(MAX) = ''
DECLARE #SQL NVARCHAR(MAX) = ''
SELECT #SQL1 = STUFF((SELECT ',' + QUOTENAME(Type_Ds) + ',' + QUOTENAME(Type_Ds + ' Expected Date') + ',' + QUOTENAME(Type_Ds + ' Completed Date')
from dbo.AppType
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
print #SQL1
SET #SQL = 'SELECT *
FROM ( SELECT A.Pro_Id,
Type_DS
FROM dbo.Project A left join [dbo].[Prj_App] B on A.Pro_id = B.Pro_Id
right outer join dbo.AppType C on B.App_Id = C.App_ID
) data
PIVOT
( MAX(Type_DS)
FOR Type_DS IN (' + #SQL1 + ')
) pvt1
where Pro_Id is not null'
print #SQL
EXECUTE SP_EXECUTESQL #SQL
Pro_Id RMC2 RMC2ExpeDt RMC2ComDt RMC1 RMC1ExpeDt RMC1ComDt
1 RMC2 NULL NULL RMC1 NULL NULL
2 NULL NULL NULL RMC1 NULL NULL.
can anyone help on it...
My suggestion when you are working with dynamic SQL is to always write the query hard-coded first, so you can get the logic correct, then convert it to dynamic SQL.
Since you are attempting to pivot 3 columns of data I would first unpivot the type_ds, expdt and comdt` columns, then apply the PIVOT function.
The hard-coded version of the query will be:
SELECT *
FROM
(
select pro_id,
type_ds = case
when col ='type_ds'
then type_ds
else type_ds+col end,
value
from
(
SELECT A.Pro_Id,
c.Type_DS,
convert(varchar(10), b.ExpDt, 120) ExpDt,
convert(varchar(10), b.ComDt, 120) ComDt
FROM dbo.Project A
left join [dbo].[Prj_App] B
on A.Pro_id = B.Pro_Id
right outer join dbo.Approval_Type C
on B.App_Id = C.App_ID
) s
cross apply
(
select 'type_ds', type_ds union all
select 'expdt', expdt union all
select 'comdt', comdt
) c (col, value)
) data
PIVOT
(
MAX(value)
FOR Type_DS IN (RMC2, RMC2expdt, RMC2comdt,
RMC1, RMC1expdt, RMC1comdt)
) pvt1
See SQL Fiddle with Demo. Now that you have a working version of the query, you can easily convert it to dynamic SQL:
DECLARE #SQL1 NVARCHAR(MAX) = ''
DECLARE #SQL NVARCHAR(MAX) = ''
SELECT #SQL1 = STUFF((SELECT ',' + QUOTENAME(Type_Ds) + ',' + QUOTENAME(Type_Ds + 'ExpDt') + ',' + QUOTENAME(Type_Ds + 'ComDt')
from dbo.Approval_Type
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
SET #SQL = 'SELECT *
FROM
(
select pro_id,
type_ds = case
when col =''type_ds''
then type_ds
else type_ds+col end,
value
from
(
SELECT A.Pro_Id,
c.Type_DS,
convert(varchar(10), b.ExpDt, 120) ExpDt,
convert(varchar(10), b.ComDt, 120) ComDt
FROM dbo.Project A
left join [dbo].[Prj_App] B
on A.Pro_id = B.Pro_Id
right outer join dbo.Approval_Type C
on B.App_Id = C.App_ID
) s
cross apply
(
select ''type_ds'', type_ds union all
select ''expdt'', expdt union all
select ''comdt'', comdt
) c (col, value)
) data
PIVOT
(
MAX(value)
FOR Type_DS IN (' + #SQL1 + ')
) pvt1 '
--print #SQL
EXECUTE SP_EXECUTESQL #SQL
See SQL Fiddle with Demo