Error converting data type varchar to numeric dynamic pivot - sql

I am getting an error described in the title where my code looks like this:
declare
#cols numeric(10,0),
#sql numeric(10,0)
select #cols = isnull(#cols + ', ', '') + '[' + T.AmountPayd + ']' from (select distinct AmountPayd from t1) as T
select #sql = '
select *
from t1 as T
pivot
(
sum(T.AmountPayd) for T.Customer in (' + #cols + ')
) as P'
exec sp_executesql #sql = #sql
The error occurs at this line:
select #cols = isnull(#cols + ', ', '') + '[' + T.AmountPayd + ']' from (select distinct AmountPayd from t1) as T
In my table AmountPayd is declared as numeric data type.
The error I get is:
Msg 8114, Level 16, State 5, Line 108 Error converting data type
varchar to numeric.

You've declared #cols as numeric(10,0), but you're trying to assign text to it.
Probably need to declare it as nvarchar(max).
P.s.
by concatenating AmountPayd you're suppose to get a list of customers?

declare
--#cols numeric(10,0),
--#sql numeric(10,0)
#cols varchar(max),
#sql varchar(max)
--Here you are setting #cols to a concatenated list of the amounts in your table
--The problem is you are trying to concat a decimal or integer into a string without casting it
--This is the same as doing 'A' + 1 and wanting to get A1. You first have to cast it.
--Notice the CAST(T.AmountPayd AS VARCHAR). But cols still needs to be a varchar in your declaration.
select #cols = isnull(#cols + ', ', '') + '[' + CAST(T.AmountPayd AS VARCHAR) + ']' from (select distinct AmountPayd from t1) as T
--Here you are building your dynamic SQL, which is a string which is why #sql must be varchar or nvarchar
select #sql = '
select *
from t1 as T
pivot
(
sum(T.AmountPayd) for T.Customer in (' + #cols + ')
) as P'
exec sp_executesql #sql = #sql
You've almost copied this example line for line, you just missed the declaration of your variables.
http://sqlhints.com/2014/03/18/dynamic-pivot-in-sql-server/

Related

SQL - Pivoting on Column and Row Values

I'm trying to Pivot a Table on X and Y position. The table is in a format similar to below.
Each row has a value which is relative to its Row and Column Position.'AThing' and 'FileName' are to be ignored in the data set.
So if this was pivoted we would get:
Iv'e been trying for a while but can't seem to figure it out, any ideas?
EDIT: Number of Fields are dynamic per 'FileName'. I have managed to extract the column names but not the data using:
-- Construct List of Columns to Pivot
SELECT #PivotCols =
STUFF(
(SELECT ',' + QUOTENAME(FieldName)
FROM #Data
GROUP BY ColPos, FieldName
ORDER BY ColPos ASC
FOR XML PATH(''),TYPE).value('.', 'NVARCHAR(MAX)')
,1,1,'')
SET #PivotQuery =
SELECT ' + #PivotCols + N'
FROM
(
SELECT ColPos, FieldName
FROM #Data
GROUP BY ColPos, FieldName
) x
PIVOT
(
MIN(ColPos)
FOR FieldName IN (' + #PivotCols + N')
) p'
EXEC sp_executesql #PivotQuery
Please try this code:
DECLARE #columns NVARCHAR(MAX), #sql NVARCHAR(MAX);
SET #columns = N'';
SELECT #columns += N', p.' + QUOTENAME(FieldName)
FROM (SELECT distinct p.FieldName FROM Tablename AS p
) AS x;
SET #sql = N'
SELECT ' + STUFF(#columns, 1, 2, '') + '
FROM
(
SELECT p.Value, p.FieldName, p.RowPos
FROM Tablename AS p
) AS j
PIVOT
(
MAX(Value) FOR FieldName IN ('
+ STUFF(REPLACE(#columns, ', p.[', ',['), 1, 1, '')
+ ')
) AS p;';
PRINT #sql;
EXEC sp_executesql #sql;

is any other way to do in dynamic pivot

while answering one question i got struck with other question in mind.when it is normal pivot it is working fine but if i'm trying to do Dynamic query when the problem arises
after answering he asked for Dynamic Pivot
PIVOT the date column in SQL Server 2012
if OBJECT_ID('tempdb..#temp') is not null
begin
drop table #temp
end
CREATE table #temp (dated varchar(10),E1 int,E2 int,E3 int,E4 int)
insert into #temp
(dated,E1,E2,E3,E4)values
('05-27-15',1,1,2,3),
('05-28-15',2,3,NULL,5),
('05-29-15',3,4,null,2)
DECLARE #statement NVARCHAR(max)
,#columns NVARCHAR(max)
SELECT #columns = ISNULL(#columns + ', ', '') + N'[' + tbl.dated + ']'
FROM (
SELECT DISTINCT dated
FROM #temp
) AS tbl
SELECT #statement = 'Select P.col,MAX('+#columns+') from (
select col,' + #columns + ' from (
select * from #temp
CROSS APPLY(values(''E1'',E1),(''E2'',E2),(''E3'',E3),(''E4'',E4))cs (col,val))PP
PIVOT(MAX(val) for dated IN (' + #columns + ')) as PVT)P
GROUP BY P.COL
'
PRINT #statement
EXEC sp_executesql #statement = #statement
my problem is how can i take MAX() conditions for the all dates dynamically like
max(05-27-15),max(05-28-15) etc dates are coming dynamically how to assign max condition
Moving the MAX aggregate to column list variable will fix the issue
DECLARE #statement NVARCHAR(max),
#columns NVARCHAR(max),
#select_columns NVARCHAR(max)
SELECT #select_columns = Isnull(#select_columns + ', ', '')+ N'MAX([' + tbl.dated + '])'
FROM (SELECT DISTINCT dated
FROM #temp) AS tbl
SELECT #columns = Isnull(#columns + ', ', '') + N'[' + tbl.dated+ ']'
FROM (SELECT DISTINCT dated
FROM #temp) AS tbl
SELECT #statement = 'Select P.col,' + #select_columns
+ ' from (
select col,' + #columns
+ ' from (
select * from #temp
CROSS APPLY(values(''E1'',E1),(''E2'',E2),(''E3'',E3),(''E4'',E4))cs (col,val))PP
PIVOT(MAX(val) for dated IN (' + #columns
+ ')) as PVT)P
GROUP BY P.COL
'
PRINT #statement
EXEC sp_executesql #statement = #statement

SQL Pivot Query

I have the below data in SQL:
Now, I would like to pivot it base on the "CostCenterNumber" field to obtain this:
Try this one:
DECLARE #cols as varchar(max)
DECLARE #sql as varchar(max)
SELECT #cols = coalesce(#cols + ',','') + '[' + CostCenterNumber + ']' FROM #MyTable
SET #sql =
'SELECT Year, GLClass, Code, GLDescription, ' + #cols + '
FROM (
SELECT *
FROM #MyTable
) as P
PIVOT
(
SUM(Total)FOR [CostCenterNumber] IN (' + #cols + ')
)AS pvt'
EXEC(#sql)
I suggest you to use where and between condition from your query

Dynamic variable store results in temp table and variable error

I have a dynamic PIVOT that partially works. It works when I don't request a where clause using a variable but just use a specific number.
I also want to be able to store the results into a temp table.
Is it possible to have a where clause variable in a dynamic pivot and is it possible to save the results to a temp table?
Here is my current query that is not working
declare #CourseID int = 2
DECLARE
#cols AS NVARCHAR(MAX),
#query AS NVARCHAR(MAX)
SET #cols = STUFF((SELECT distinct ',' + QUOTENAME(UnitID)
FROM LMS_Unit_Status where CourseID = #CourseID
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set #query = 'SELECT LearnerID, ' + #cols + ' from
(select LearnerID,UnitID,Completed from LMS_Unit_Status where CourseID = #CourseID) as s
pivot
(
min(Completed)
for UnitID in (' + #cols + ')
) p'
execute(#query);
Msg 137, Level 15, State 2, Line 2
Must declare the scalar variable "#CourseID".
Thanks
If #CurseID is a variable parser should know it is a variable and not a string
And since you have no idea how many columns table will have you can simply use select into statement.
set #query = 'SELECT LearnerID, ' + #cols + ' into tempTable from
(select LearnerID,UnitID,Completed from LMS_Unit_Status where CourseID = ' + #CourseID + ') as s
pivot
(
min(Completed)
for UnitID in (' + #cols + ')
) p
select * from tempTable
drop table tempTable'
execute(#query);
Cheers!

Conversion failed when converting date and/or time from character string

I am struggling with this query which returns the error: Conversion failed when converting date and/or time from character string.
This is a common error judging from my google searches, but nothing I've tried so far works. I've tried casting #startdate as datetime and varchar and leaving it alone, as in the below example.
I've also tried using convert against the fieldname and the parameter name, although admittedly, I may just be getting the syntax wrong.
ALTER PROCEDURE [dbo].[customFormReport]
(
#formid int,
#startdate DATETIME
)
AS
BEGIN
SET NOCOUNT ON
DECLARE #cols AS NVARCHAR(MAX),
#query AS NVARCHAR(MAX)
select #cols = STUFF((SELECT distinct ',' + QUOTENAME(fieldname) from FormResponse WHERE FormID = #formid AND value IS NOT NULL FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set #query = 'SELECT FormID, FormSubmissionID,' + #cols + ' from
(
SELECT FormID, FormSubmissionID, fieldname, value
FROM FormResponse WHERE FormID = ' + CAST(#formid AS VARCHAR(25)) + ' AND createDate > ' + #startdate + '
) x
pivot
(
max(value)
for fieldname in (' + #cols + ')
) p '
execute(#query)
edit: the query works except when I add the bit causing the error:
' AND createDate > ' + #startdate + '
The problem is you are attempting to concatenate a datetime to your varchar sql string. You need to convert it:
convert(varchar(10), #startdate, 120)
So the full code will be:
ALTER PROCEDURE [dbo].[customFormReport]
(
#formid int,
#startdate DATETIME
)
AS
BEGIN
SET NOCOUNT ON
DECLARE #cols AS NVARCHAR(MAX),
#query AS NVARCHAR(MAX)
select #cols = STUFF((SELECT distinct ',' + QUOTENAME(fieldname) from FormResponse WHERE FormID = #formid AND value IS NOT NULL FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set #query = 'SELECT FormID, FormSubmissionID,' + #cols + ' from
(
SELECT FormID, FormSubmissionID, fieldname, value
FROM FormResponse
WHERE FormID = ' + CAST(#formid AS VARCHAR(25)) + '
AND createDate > ''' + convert(varchar(10), #startdate, 120) + '''
) x
pivot
(
max(value)
for fieldname in (' + #cols + ')
) p '
execute(#query)
When you dynamically build the SQL Statement, the date value needs to be wrapped in single quotes. Whenever building a dynamic statement, do a SELECT #query and make sure the results look correct.
For your example, you would need to have 'WHERE createdate > ''' + covert(varchar(10), #startdate, 111) + '''
That would output: WHERE createdate > '2013/05/29'
Without the single quotes you would have: WHERE createdate > 2013/05/29