Dynamic query in SSIS expression builder throwing an error expression cannot be evaluated - ssis

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'

Related

Using dynamic dates in a SQL pivot

I have the below code that works well but I don't want to continue typing in the dates daily.
My dates will always be the last 7 days (including today) - meaning that the table will be purged daily and the new data pull in daily.
select *
from
(
select EMP_ID, EMP_SHORT_NAME, SEG_CODE,
NOM_DATE
from sick_codes_Test$
) src
pivot
(
max(seg_code)
for nom_date in ([2018-07-14], [2018-07-15],[2018-07-16],[2018-07-17],[2018-07-18],
[2018-07-19], [2018-07-20])
) piv
So for "nom_date in" how can I make those dates the dates that will just be in the table?
I tried following along with the following link
https://www.mssqltips.com/sqlservertip/2783/script-to-create-dynamic-pivot-queries-in-sql-server/
But wasn't able to make it work
From following the above URL I came up with this code
DECLARE #columns NVARCHAR(MAX), #sql NVARCHAR(MAX);
SET #columns = N'';
SELECT #columns += N',' + QUOTENAME(NOM_DATE)
FROM sick_codes_Test$
SET #sql = N'
SELECT ' + STUFF(#columns, 1, 2, '') + '
FROM
(
SELECT EMP_ID, EMP_SHORT_NAME, SEG_CODE
from sick_codes_Test$
) AS j
PIVOT
(
max(seg_code) FOR nom_date IN ('
+ STUFF(REPLACE(#columns, ', [', ',['), 1, 1, '')
+ ')
) AS p;';
PRINT #sql;
EXEC sp_executesql #sql;
Any help would be greatly appreciated.
After more digging around I think I found a possible solution but after running the below I seeing the EMP_ID being duplicated.
DECLARE #DynamicPivotQuery AS NVARCHAR(MAX)
DECLARE #ColumnName AS NVARCHAR(MAX)
--Get distinct values of the PIVOT Column
SELECT #ColumnName= ISNULL(#ColumnName + ',','')
+ QUOTENAME(NOM_DATE)
FROM (SELECT DISTINCT NOM_DATE FROM sick_codes_Test$ ) AS NOM_DATE
order by NOM_DATE ASC
--Prepare the PIVOT query using the dynamic
SET #DynamicPivotQuery =
N'SELECT EMP_ID, EMP_SHORT_NAME, ' + #ColumnName + '
FROM sick_codes_Test$
PIVOT(MAX(SEG_CODE)
FOR NOM_DATE IN (' + #ColumnName + ')) AS PVTTable'
--Execute the Dynamic Pivot Query
EXEC sp_executesql #DynamicPivotQuery
After more modifications I finally found a solution that worked
DECLARE #DynamicPivotQuery AS NVARCHAR(MAX)
DECLARE #ColumnName AS NVARCHAR(MAX)
--Get distinct values of the PIVOT Column
SELECT #ColumnName= ISNULL(#ColumnName + ',','')
+ QUOTENAME(NOM_DATE)
FROM (SELECT DISTINCT NOM_DATE FROM sick_codes_Test$ ) AS NOM_DATE
order by NOM_DATE ASC
--Prepare the PIVOT query using the dynamic
SET #DynamicPivotQuery =
N'SELECT EMP_ID, EMP_SHORT_NAME, ' + #ColumnName + '
FROM (
SELECT DISTINCT EMP_ID,
EMP_SHORT_NAME,
SEG_CODE,
NOM_DATE
FROM sick_codes_Test$
)t
PIVOT(MAX(SEG_CODE)
FOR NOM_DATE IN (' + #ColumnName + ')) AS PVTTable'
--Execute the Dynamic Pivot Query
EXEC sp_executesql #DynamicPivotQuery

How to replace NULL to 0 in pivot table output values

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);

How do I pivot with hour format(HH:HourNumber)?

I have OrderInfo table which contains OrderTime(date+time),OrderTrackDate(date),OrderTotal(sales amount) columns as shown in the following image.
1. Table1(Original Table)
Here is the code I have tried so far before pivoting.
SELECT CAST(DATEPART(DAY, OrderTime) as varchar)+'/'+ CAST(DATEPART(MONTH, OrderTime) as varchar)+'/'+CAST(DATEPART(year,OrderTime) as varchar) as daymonthyear,
ROUND(SUM(OrderTotal),2) AS Sales, COUNT(OrderTotal) AS Orders
,datepart(hour,OrderTime) as HH
FROM OrderInfo where OrderTime >= '5/24/2013' AND OrderTrackDate <='5/30/2013'
GROUP BY DATEPART(year, OrderTime),DATEPART(MONTH, OrderTime),DATEPART(day, OrderTime),datepart(hour,OrderTime)
Order By daymonthyear,HH
2. Table 2(Grouped according to Date,Hour from Table1)
How do I pivot dynamically and show sales amount per hour based on Table2?
DESIRED OUTPUT
First of all create a temp table to use it in 3 places - Select columns for pivot, Replace null with zero and inside pivot.
SELECT DISTINCT
SUM(ORDERTOTAL) OVER(PARTITION BY CAST(ORDERTIME AS DATE),DATEPART(HH,ORDERTIME)) [TOTAL],
CONVERT(varchar, CAST(ORDERTIME AS datetime), 103) [DATE],
DATEPART(HH,ORDERTIME) [HOUR],
'HH:'+CAST(DATEPART(HH,ORDERTIME) AS VARCHAR(3)) [HOURCOL]
INTO #NEWTABLE
FROM ORDERTBL
ORDER BY DATEPART(HH,ORDERTIME)
Now declare 2 variables to select columns for pivot and replace null with zero
DECLARE #cols NVARCHAR (MAX)
DECLARE #NullToZeroCols NVARCHAR (MAX)
SELECT #cols = COALESCE (#cols + ',[' + [HOURCOL] + ']',
'[' + [HOURCOL] + ']')
FROM (SELECT DISTINCT [HOUR],[HOURCOL] FROM #NEWTABLE) PV
ORDER BY [HOUR]
SET #NullToZeroCols = SUBSTRING((SELECT ',ISNULL(['+[HOURCOL]+'],0) AS ['+[HOURCOL]+']'
FROM(SELECT DISTINCT [HOUR],[HOURCOL] FROM #NEWTABLE GROUP BY [HOUR],[HOURCOL])TAB
ORDER BY [HOUR] FOR XML PATH('')),2,8000)
Now pivot the result
DECLARE #query NVARCHAR(MAX)
SET #query = 'SELECT [DATE],' + #NullToZeroCols + ' FROM
(
SELECT [HOURCOL],[TOTAL], [DATE] FROM #NEWTABLE
) x
PIVOT
(
SUM([TOTAL])
FOR [HOURCOL] IN (' + #cols + ')
) p
;'
EXEC SP_EXECUTESQL #query
SQL FIDDLE

ambiguous column name error sql server 2008

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)

How to rename column with prefixes of a result table, the result table is obtained using pivot 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