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

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

Related

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

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]

Inserting dynamic pivot result into an existing table without knowing table definition

I have a dynamic pivot table that produces an unknown number of columns until runtime. I am trying to clear the data out of an existing table and insert the results of my query into it. The problem that I am having is that I do not know what the table definition will be ahead of time because it is dynamic.
Here is the error I am getting:
Msg 213, Level 16, State 7, Line 1
Column name or number of supplied values does not match table definition.
The pivoted column is a date column which could have 1 date or 1000+ dates.
How can I create a table definition that will match the data that I am trying to insert?
Here is my query:
DECLARE #colsPivot AS NVARCHAR(MAX),
#colsUnpivot AS NVARCHAR(MAX),
#query AS NVARCHAR(MAX)
select #colsPivot = STUFF((SELECT ',' + QUOTENAME(rce.EcoDate)
from PhdRpt.RptCaseEco_542 AS rce
group by rce.EcoDate
order by rce.EcoDate
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
SELECT #colsUnpivot = stuff((SELECT ','+quotename(C.name)
FROM sys.columns AS C
WHERE C.object_id = object_id('PhdRpt.RptCaseEco_542') AND
C.name in ('NDCash', 'DCash')--LIKE '%Cash' or C.Name like 'NetGas'
FOR xml path('')), 1, 1, '')
set #query
= 'select *
--into ##hello
from
(
SELECT
ReportRunCaseId,
col,
EcoDate,
val
FROM PhdRpt.RptCaseEco_542
unpivot
(
val
for col in ('+ #colsunpivot +')
) u
) x1
pivot
(
max(val)
for EcoDate in ('+ #colspivot +')
) p'
truncate table dbo.Table1
insert into dbo.Table1
exec(#query)
I would DROP original table and just create new one on the fly using SELECT INTO clause.
by using SELECT INTO you do not need to create table before hand or worry what type and how many columns it will have. SQL Server will just create it for you.
Note: this only works when table does not exists.
Full documentation on INTO Clause http://technet.microsoft.com/en-us/library/ms188029.aspx
as another alternative you can always SELECT INTO #temp table that you can drop or use it to model your other table but I think this is extra work that you do not want to do.
You can do something like this:
DROP TABLE dbo.Table1
DECLARE #colsPivot AS NVARCHAR(MAX),
#colsUnpivot AS NVARCHAR(MAX),
#query AS NVARCHAR(MAX)
select #colsPivot = STUFF((SELECT ',' + QUOTENAME(rce.EcoDate)
from PhdRpt.RptCaseEco_542 AS rce
group by rce.EcoDate
order by rce.EcoDate
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
SELECT #colsUnpivot = stuff((SELECT ','+quotename(C.name)
FROM sys.columns AS C
WHERE C.object_id = object_id('PhdRpt.RptCaseEco_542') AND
C.name in ('NDCash', 'DCash')--LIKE '%Cash' or C.Name like 'NetGas'
FOR xml path('')), 1, 1, '')
set #query
= 'select *
into dbo.Table1
from
(
SELECT
ReportRunCaseId,
col,
EcoDate,
val
FROM PhdRpt.RptCaseEco_542
unpivot
(
val
for col in ('+ #colsunpivot +')
) u
) x1
pivot
(
max(val)
for EcoDate in ('+ #colspivot +')
) p'
exec(#query)

Dynamic pivot table with multiple columns in sql server

I am trying to pivot table DYNAMICALLY but couldn't get the desired result.
Here is the code to create a table
create table Report
(
deck char(3),
Jib_in float,
rev int,
rev_insight int,
jib_out float,
creation int
)
insert into Report values
('A_1',0.345,0,0,1.23,20140212),
('B_2',0.456,0,4,2.34,20140215),
('C_3',0.554,0,6,0.45,20140217),
('D_4',0.231,0,8,7.98,20140222),
('E_5',0.453,0,0,5.67,20140219),
('F_6',0.344,0,3,7.23,20140223)'
Code written so far.... this pivots the column deck and jib_in into rows but thats it only TWO ROWS i.e the one i put inside aggregate function under PIVOT function and one i put inside QUOTENAME()
DECLARE #columns NVARCHAR(MAX), #sql NVARCHAR(MAX);
SET #columns = N'';
SELECT #columns += N', p.' + QUOTENAME(deck)
FROM (SELECT p.deck FROM dbo.report AS p
GROUP BY p.deck) AS x;
SET #sql = N'
SELECT ' + STUFF(#columns, 1, 2, '') + '
FROM
(
SELECT p.deck, p.jib_in
FROM dbo.report AS p
) AS j
PIVOT
(
SUM(jib_in) FOR deck IN ('
+ STUFF(REPLACE(#columns, ', p.[', ',['), 1, 1, '')
+ ')
) AS p;';
PRINT #sql;
EXEC sp_executesql #sql;
I need all the columns to be pivoted and show on the pivoted table. any help would be appreciated. I am very new at dynamic pivot. I tried so many ways to add other columns but no avail!!
I know there are other ways please feel free to mention if there is any other way to get this right.
Please use this (If you are getting Collation issue, please change all the 3 INT datatypes):
STATIC code:
SELECT HEADER, [A_1],[B_2],[C_3],[D_4],[E_5],[F_6]
FROM
(SELECT DECK,HEADER, VALUE FROM REPORT
UNPIVOT
(
VALUE FOR HEADER IN ([JIB_IN],[REV],[REV_INSIGHT],[JIB_OUT],[CREATION])
) UNPIV
) SRC
PIVOT
(
SUM(VALUE)
FOR DECK IN ([A_1],[B_2],[C_3],[D_4],[E_5],[F_6])
) PIV
Using Dynamic SQL:
DECLARE #COLSUNPIVOT AS NVARCHAR(MAX),
#QUERY AS NVARCHAR(MAX),
#COLSPIVOT AS NVARCHAR(MAX)
SELECT #COLSUNPIVOT = STUFF((SELECT ','+QUOTENAME(C.NAME)
FROM SYS.COLUMNS AS C
WHERE C.OBJECT_ID = OBJECT_ID('REPORT') AND C.NAME <> 'DECK'
FOR XML PATH('')), 1, 1, '')
SELECT #COLSPIVOT = STUFF((SELECT ',' + QUOTENAME(DECK)
FROM REPORT T FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)') ,1,1,'')
SET #QUERY
= 'SELECT HEADER, '+#COLSPIVOT+'
FROM
(
SELECT DECK,HEADER,VALUE FROM REPORT
UNPIVOT
(
VALUE FOR HEADER IN ('+#COLSUNPIVOT+')
) UNPIV
) SRC
PIVOT
(
SUM(VALUE)
FOR DECK IN ('+#COLSPIVOT+')
) PIV'
EXEC(#QUERY)

T-SQL:Transform variable number of rows into columns

When I run a SQL query which returns one column with variable number of rows returned, I'd like to transform each of the row into column VALUE (I don't mind what the column header/titles are).
E.g.
Column1
-------
a
b
c
d
e
I want a script which will transform the above into a table like:
Col1 Col2 Col3 Col4 Col5
------------------------
a b c d e
(Note that I do not care for the column names).
I know I cannot user PIVOT as row numbers are not fixed (they are based on a SQL query).
Any ideas?
Thanks!
You're trying to pivot your results and include a counter in your column name. Since I'm presuming you don't know the potential number of columns, you'll need to use Dynamic SQL to accomplish this.
This should be close using ROW_NUMBER to get the counter:
declare #cols AS NVARCHAR(MAX),
#colswithalias AS NVARCHAR(MAX),
#query AS NVARCHAR(MAX)
set #colswithalias = STUFF((SELECT distinct ',' + QUOTENAME(col1)
+ ' AS Col'
+ CAST(ROW_NUMBER() OVER (ORDER BY col1) as varchar(10))
FROM yourtable
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set #cols = STUFF((SELECT distinct ',' + QUOTENAME(col1)
FROM yourtable
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set #query = 'SELECT ' + #colswithalias + '
from
(
select col1 rn, col1
from yourtable
) x
pivot
(
max(rn)
for col1 in (' + #cols + ')
) p '
execute(#query)
SQL Fiddle Demo

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