SQL Removing a filter from an unpivot table - sql

I have this unpivot table and I wish to remove the filter that is applied to it.
DECLARE #colsPivot AS NVARCHAR(MAX),
#colsUnpivot as NVARCHAR(MAX),
#query AS NVARCHAR(MAX)
select #colsPivot = STUFF((SELECT distinct ',' + QUOTENAME(year(EcoDate))
from PhdRpt.RptCaseEco
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')
and C.name Like 'Net%'
for xml path('')), 1, 1, '')
set #query
= 'select *
from
(
select reportruncaseid, year(Ecodate) as EcoYear, val, col
from phdrpt.rptcaseeco
unpivot
(
val
for col in ('+ #colsUnpivot +')
) u
) x1
pivot
(
max(val)
for ecoyear in ('+ #colspivot +')
) p ORDER BY reportruncaseid'
exec(#query)
This table worked before because all the columns had a prefix of "Net" but now there are other columns that are being filtered out because they do not begin with "Net". I tried to remove --- and C.name Like 'Net%' --- but I keep getting these errors:
Msg 8167, Level 16, State 1, Line 10
The type of column "EcoDate" conflicts with the type of other columns specified in the UNPIVOT list.
Msg 207, Level 16, State 1, Line 4
Invalid column name 'reportruncaseid'.
Msg 207, Level 16, State 1, Line 4
Invalid column name 'Ecodate'.
Here is what the table looks like

The filter to get the list of columns to UNPIVOT can be removed but if there are columns that you do not want to UNPIVOT then you will need to exclude them:
select #colsUnpivot = stuff((select ','+quotename(C.name)
from sys.columns as C
where C.object_id = object_id('PhdRpt.RptCaseEco')
and C.name not in ('reportruncaseid', 'Ecodate')
for xml path('')), 1, 1, '')
This will return all of the columns to unpivot, except reportruncaseid and Ecodate (or other columns you do not want unpivoted). So the full query will be:
DECLARE #colsPivot AS NVARCHAR(MAX),
#colsUnpivot as NVARCHAR(MAX),
#query AS NVARCHAR(MAX)
select #colsPivot = STUFF((SELECT distinct ',' + QUOTENAME(year(EcoDate))
from PhdRpt.RptCaseEco
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')
and C.name not in ('reportruncaseid', 'Ecodate')
for xml path('')), 1, 1, '')
set #query
= 'select *
from
(
select reportruncaseid, year(Ecodate) as EcoYear, val, col
from phdrpt.rptcaseeco
unpivot
(
val
for col in ('+ #colsUnpivot +')
) u
) x1
pivot
(
max(val)
for ecoyear in ('+ #colspivot +')
) p ORDER BY reportruncaseid'
exec(#query);
Also if you have columns that are different datatypes, then you will have to cast them to the same datatype prior to applying the unpivot.

Related

Dynamic pivot in SQL : conversion failed

I have a table that date/time filed is nvarchar type when I create pivot table I get this error:
Msg 245, Level 16, State 1, Line 12
Conversion failed when converting the nvarchar value 'SELECT pr[آماده سازی],[فنی],[غیر فنی],[متفرقه],[CIP],[نامنطبق],[نت],[نظافت],[مواد اولیه] from
(
select stoptime,(prdname+convert(nvarchar,prsize))pr,stoptypetext
from Table_stop
where formnum in (select prdID from Table_production where prddate=iif(1398/06/04 is null,prddate,1398/06/04)
and prdgroup=iif(شب is null,prdgroup,شب) and idline=iif(' to data type int.
My code is:
DECLARE #cols AS NVARCHAR(MAX),
#query AS NVARCHAR(MAX),
#date NVARCHAR(10) = '1398/06/04',
#pgroup NVARCHAR(150) = N'شب',
#idline INT = 4
SELECT #cols = STUFF((SELECT ',' + QUOTENAME(stopTYPE)
FROM Table_stoptype
GROUP BY stopTYPE, stopid
ORDER BY stopid
FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'), 1, 1, '')
SET #query = N'SELECT pr' + #cols + N' from
(
select stoptime,(prdname+convert(nvarchar,prsize))pr,stoptypetext
from Table_stop
where formnum in (select prdID from Table_production where prddate=iif('+#date+' is null,prddate,'+#date+')
and prdgroup=iif('+#pgroup+' is null,prdgroup,'+#pgroup+') and idline=iif('+#idline+' is null,idline,'+#idline+'))
) x
pivot
(
sum(stoptime)
for stoptypetext in (' + #cols + N')
) p '
EXEC sp_executesql #query;

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

Reverse Table In SQL

I have query:
SELECT DISTINCT temp.ID,request.RequestTypeID
FROM #MyTempTable6 as temp
JOIN dbo.FingerMachineUsers as fingeruser
ON temp.UserNo = fingeruser.ID
JOIN dbo.AppUsers as appuser
ON appuser.Id = fingeruser.UserId
LEFT JOIN dbo.Requests as request
ON request.UserId = fingeruser.UserId
And result of it:
How can I create table like this:
ID|RequestTypeID1|RequestTypeID2
1 | 4| 5
If you have only two values, then the simplest method is aggregation:
SELECT t.ID, MIN(r.RequestTypeID), MAX(r.RequestTypeID)
FROM #MyTempTable6 t JOIN
dbo.FingerMachineUsers fu
ON t.UserNo = fu.ID JOIN
dbo.AppUsers au
ON au.Id = fu.UserId LEFT JOIN
dbo.Requests r
ON r.UserId = fu.UserId
GROUP BY t.ID;
If you have have a variable number of values that you want to present, then the query is much more complicated.
PIVOT operator could be your best friend, if there are always only 2 values each...
Try this query...
Disclaimer: This code is purely based on this answer. (https://stackoverflow.com/a/10404455/6327676)
DECLARE #cols AS NVARCHAR(max),
#query AS NVARCHAR(max);
SET #cols = Stuff((SELECT DISTINCT ',' + Quotename(stff.requesttypeid)
FROM TableName stff
FOR xml path(''), type).value('.', 'NVARCHAR(MAX)'), 1, 1, ''
)
SET #query = 'SELECT ID, '+ #cols
+ ' FROM (select ID, RequestTypeId FROM TableName) x pivot (MAX(RequestTypeId) FOR RequestTypeId in ('
+ #cols + ')) p'
EXECUTE(#query)
Try this code it will work according to the result you want.
Firstly you need to dump #MyTempTable6 table into #temptable
then set RequestTypeID columns as comma seperated in #colums varible then set the columnname in #Requestcolumns variable,Then use pivot.
DECLARE #colums AS NVARCHAR(max)
DECLARE #Requestcolumns AS NVARCHAR(max)
DECLARE #query AS NVARCHAR(max);
SELECT DISTINCT temp.ID,request.RequestTypeID
into #temptable
FROM #MyTempTable6 as temp
JOIN dbo.FingerMachineUsers as fingeruser
ON temp.UserNo = fingeruser.ID
JOIN dbo.AppUsers as appuser
ON appuser.Id = fingeruser.UserId
LEFT JOIN dbo.Requests as request
ON request.UserId = fingeruser.UserId
SET #colums = Stuff((SELECT DISTINCT ',' +Quotename(tab.RequestTypeID)
FROM #temptable tab
FOR xml path(''), type).value('.', 'NVARCHAR(MAX)'), 1, 1, ''
)
SET #Requestcolumns = Stuff((SELECT DISTINCT ',' +Quotename(tab.RequestTypeID) +' AS ',+Quotename('RequestTypeID'+CONVERT(varchar(100),tab.RequestTypeID))
FROM #temptable tab
FOR xml path(''), type).value('.', 'NVARCHAR(MAX)'), 1, 1, ''
)
SET #query = 'SELECT ID, '+#Requestcolumns
+ ' FROM (select ID, RequestTypeID FROM #temptable) x pivot (MAX(RequestTypeID) FOR RequestTypeID in ('
+ #colums + ')) p'
EXECUTE(#query)
DROP table #temptable

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)