trying to average column with CAST in PIVOT table- Incorrect syntax near '(' - sql

I am trying the Pivot function to get the following table-
split rows of TagID into columns, the TagValue of each TagID and DATEADD TimeStamp to display avg values every 5 minutes:
DECLARE #cols AS NVARCHAR(MAX),
#query AS NVARCHAR(MAX)
select #cols = STUFF((SELECT ',' + QUOTENAME(TagID)
from table
group by TagID
order by TagID
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set #query = 'SELECT Top (500) DATEADD(minute,DATEDIFF(minute,0,TimeStamp)/5*5,0) AS TimeStamp, ' + #cols + ' from
(
select TimeStamp, TagID , TagValue
from table
Group By TimeStamp, TagID, TagValue
) x
pivot
(
AVG(CAST(TagValue) AS DECIMAL(18,2))
for TagID in ( ' + #cols + ' )
) p '
execute(#query)
I am trying to create avg for the column TagValue.
After I used the CAST function as you can see above, the query displayed:
Msg 102, Level 15, State 1, Line 12
Incorrect syntax near '('.
although I cannot find what is wrong and which exact syntax is incorrect.
Would really appreciate some help here as Management studio doesn't show where the problem is.
I looked up online and normally the avg function is used like this:
AVG(TagValue) although it doesn't work on NVARCHAR column.

There was syntax issue with the CAST statement, also minor changes were made to sub query table x - please try the below code
DECLARE #cols AS NVARCHAR(MAX),
#query AS NVARCHAR(MAX)
SELECT #cols = STUFF((SELECT ',' + QUOTENAME(TagID)
FROM table
GROUP BY TagID
ORDER BY TagID
FOR XML PATH(''), TYPE ).value('.', 'NVARCHAR(MAX)') ,1,1,'')
SET #query = 'SELECT TOP (500) DATEADD(minute,DATEDIFF(minute,0,TimeStamp)/5*5,0) AS TimeStamp, ' + #cols + ' from
(
select TimeStamp, TagID , TRY_CAST(TagValue AS DECIMAL(18,2)) AS [TagValue]
from table
Group By TimeStamp, TagID, TagValue
) x
pivot
(
AVG(TagValue)
for TagID in ( ' + #cols + ' )
) p '
EXEC(#query)

Change it to AVG(CAST(TagValue AS DECIMAL(18,2))) instead of
AVG(CAST(TagValue) AS DECIMAL(18,2)) in the pivot block.
i.e, you are using CAST(TagValue) AS DECIMAL(18,2)), but it should be CAST(TagValue AS DECIMAL(18,2))

You have issue with CAST Syntax. Use as below-
AVG(CAST(TagValue AS DECIMAL(18,2)))
You query shows table name is 'table'. Can you use the table name second bracket around as below-
FROM [table]

Related

The type of column "Date" conflicts with the type of other columns specified in the UNPIVOT list

I have the following code to do Pivot and Unpivot on a set of columns:
DECLARE #cols AS NVARCHAR(MAX),
#query AS NVARCHAR(MAX),
#colsUnpivot AS NVARCHAR(MAX)
select #colsUnpivot = stuff((select ','+quotename(C.name)
from tempdb.sys.columns as C
where C.object_id = object_id('tempdb..#TmpTable')
for xml path('')), 1, 1, '')
SET #cols = STUFF((SELECT ',' + QUOTENAME(a.Date)
FROM
(Select top 10000 date from
#TmpTable
order by date) a
group by a.Date
order by a.Date
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set #query = 'SELECT name, ' + #cols + ' from
(
select Date,name,value
from #TmpTable
unpivot
(
value for name in ('+#colsUnpivot+')
) unpiv
) x
pivot
(
sum(value)
for date in (' + #cols + ')
) p '
exec(#query)
But, I keep getting these errors which I can't figure out why:
The type of column "Date" conflicts with the type of other columns specified in the UNPIVOT list.
Invalid column name 'Date'
The type of Date column in the temp table is datetime.
This post was very helpful to explain the issue. Basically, I had to convert the values to decimal for all the columns in the inner select statement of the unpivot section:
Error : The type of column "DOB" conflicts with the type of other columns specified in the UNPIVOT list

How to to select two columns (Name, Value) and return as single result?

So I have a table that has a column for Name, and a column for Value and an ID. There can be multiple rows for the same ID. I would like to create a select that will return a single row for each ID and the values in the Name column would be the column name, and the Value would be the value. Example:
CREATE TABLE dbo.Attribute
(
AttributeID int NOT NULL,
Name varchar(20) NOT NULL,
Value varchar(20) NOT NULL
) ;
Data:
{1,"Color", "Blue"},{1,"Material", "leather"}
Would like Select to return:
[AttributeID:1, Color:Blue, Material: leather]
I have been playing with PIVOT and UNPIVOT but not getting what I need.
Thanks to #Mihai's link. I was able to do what I
DECLARE #cols AS NVARCHAR(MAX),
#query AS NVARCHAR(MAX);
SET #cols = STUFF((SELECT distinct ',' + QUOTENAME(c.Name)
FROM VariantAttribute c
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set #query = 'SELECT variantid, ' + #cols + ' from
(
select variantid
, Name
, value
from VariantAttribute
) x
pivot
(
max([Value])
for Name in (' + #cols + ')
) p '
execute(#query)
Before I get more slack about how I am storing this data. There is not a way out of it at the moment, but this query is to push this data to Azure Search (uses Elastic search) to be able to easily search on this data.

Dynamic pivot - doesnt read the '+' sign

Hi I am trying to run the below code, but getting the error below. telling me that the issue is due to ' + #Cols + ', however this code is referenced from the forums. Any help would be greatly appreciated. Thanks
Error
Msg 102, Level 15, State 1, Line 27
Incorrect syntax near ' + #Cols + '.
DECLARE #cols AS NVARCHAR(MAX),
#query AS NVARCHAR(MAX);
SET #cols = STUFF((SELECT distinct ',' + QUOTENAME(year)
FROM [Reporting].[dbo].[FX_Table]
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
SELECT *
FROM
(
SELECT
[from],
[Year],
[FX]
FROM [Reporting].[dbo].[FX_Table] WHERE [To] = 'Euro'
GROUP BY
[from],
[Year],
[FX]
) AS S
PIVOT
(
SUM(FX)
FOR [year] IN ' + #Cols + '
)
AS PVT
How about this?
SELECT *
FROM (
SELECT [from],
[Year],
[FX]
FROM [Reporting].[dbo].[FX_Table]
WHERE [To] = 'Euro'
GROUP BY [from],
[Year],
[FX]
) AS S
PIVOT(SUM(FX) FOR [year] IN (
SELECT DISTINCT year
FROM [Reporting].[dbo].[FX_Table]
)) AS PVT
You don't have to create a variable where you will store all your values and then try to use IN to go over those values and filter them.
Also, if you create a NVARCHAR variable to hold all your years, then you will have to split all those values, by comma, to use them with IN (which would make your declaration of variable #Cols useless).
What you will have in your #Cols variable, the way you create it now, is something like below (ONE record which is the list of years):
But for your IN clause to work, you would need multiple records, each year a new record, like below:
I hope this solves your problem.

sql table row - column conversion

I have following table:
How to convert the above table into below structure? I tried using pivot table but couldn't get it to work.
You need to have to look up SQL PIVOT.
Check this fiddle
And the code:
SELECT *
FROM
(
SELECT Prodname,
pcode,
Biiledamt
FROM Product
) p
PIVOT
(
SUM (Biiledamt)
FOR Prodname IN ([Prod1],[Prod2],[Prod3],[Prod4])
) AS pvt
If you do not know beforehand the columns then you can check this fiddle which dynamically generates the columns to use.
The code for that is:
DECLARE #cols AS VARCHAR(MAX),
#query AS VARCHAR(MAX)
SET #cols = STUFF((SELECT distinct ',[' + Prodname +']'
FROM Product c
FOR XML PATH(''), TYPE
).value('.', 'VARCHAR(MAX)')
,1,1,'')
SET #query =
' SELECT *
FROM
(
SELECT Prodname,
pcode,
Biiledamt
FROM Product
) p
PIVOT
(
SUM (Biiledamt)
FOR Prodname IN (' + #cols + ')
) AS pvt
'
EXEC(#query)

while converting column to row not able to fetch value from another table automatically

select *
from (
select vtid, convert(date, dtime) as Date from Transaction_tbl where locid = 5
) as vt
pivot (
count(vtid)
for vtid in (select vtid from VType_tbl)
) as pvt
while executing this query am getting error
Incorrect syntax near the keyword 'select'." and Incorrect syntax near
')'.
actually I have one more table,name= Vtype_table , How Can I load all vtid from vtype table in this query? I want to get output depend upon vtid.
Any help greatly appreciated.
Your PIVOT syntax is correct except you are using a SELECT statement inside your PIVOT.
You cannot use a SELECT statement inside the PIVOT IN clause to select column headers. It is required that the columns for the IN clause be known prior to executing the query.
If you are looking to generate a dynamic list of vtid values, then you will need to use dynamic SQL to get the result and the syntax will be similar to the following:
DECLARE #cols AS NVARCHAR(MAX),
#query AS NVARCHAR(MAX)
select #cols = STUFF((SELECT distinct ',' + QUOTENAME(vtid)
from VType_tbl
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set #query = 'SELECT Date, ' + #cols + '
from
(
select vtid, convert(date, dtime) as Date
from Transaction_tbl
where locid = 5
) d
pivot
(
count(vtid)
for vtid in (' + #cols + ')
) p '
execute(#query);
Edit, if you want the type names to appear then you should be able to use the following:
DECLARE #cols AS NVARCHAR(MAX),
#query AS NVARCHAR(MAX)
select #cols = STUFF((SELECT distinct ',' + QUOTENAME(vt_name)
from VType_tbl
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set #query = 'SELECT Date, ' + #cols + '
from
(
select v.vt_name, convert(date, dtime) as Date
from Transaction_tbl t
inner join VType_tbl v
on t.vtid = v.vtid
where locid = 5
) d
pivot
(
count(vt_name)
for vt_name in (' + #cols + ')
) p '
execute(#query)
Note: I am guessing on the column name for VType_tbl