Sql Pivoting on date - sql

I am getting this error when trying to convert the below logic in to SQL query
Logic:
TRANSFORM First([SirName] & " - " & [SecondName]) AS Name
SELECT qry_Date.RoomNumber
FROM Guest RIGHT JOIN qry_Date ON Guest.ID = qry_Date.GuestID
WHERE (((qry_Date.RoomNumber) Is Not Null))
GROUP BY qry_Date.RoomNumber
PIVOT qry_Date.Date;
Below is what i have done so far
DECLARE #cols AS NVARCHAR(MAX)
DECLARE #query AS VARCHAR(MAX)
SELECT #cols = STUFF((SELECT distinct top 100 percent
',' + QUOTENAME(convert(NVARCHAR(MAX),qry_Date.Date,103))
FROM qry_Date
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)'),1,1,'');
SET #query = 'SELECT Name, ' + #cols + '
FROM
(SELECT [SirName] + '' - '' + [SecondName] AS Name
,qry_Date.RoomNumber
,qry_Date.Date
FROM Guest RIGHT JOIN qry_DateTemp ON Guest.ID = qry_Date.GuestID
WHERE qry_Date.RoomNumber Is Not Null) as t
PIVOT
(count(Name) FOR [Date] IN( ' + #cols + ')
) as p'
print #query
execute(#query)
Which results error
Msg 8114, Level 16, State 1, Line 9 Error converting data type
nvarchar to datetime2. Msg 473, Level 16, State 1, Line 9 The
incorrect value "13/12/2014" is supplied in the PIVOT operator. Msg
207, Level 16, State 1, Line 1 Invalid column name 'Name'.
My print #query output
SELECT Name, [01/12/2014],[02/12/2014],[03/12/2014],[04/12/2014],[05/12/2014],[06/12/2014],[07/12/2014],[08/12/2014],[09/12/2014],[10/12/2014],[11/12/2014],[12/12/2014],[13/12/2014],[14/12/2014],[15/12/2014],[16/12/2014],[17/12/2014],[18/12/2014],[19/12/2014],[20/12/2014],[21/12/2014],[22/12/2014],[23/12/2014],[24/12/2014],[25/12/2014],[26/12/2014],[27/12/2014],[28/12/2014],[29/12/2014],[30/12/2014],[31/12/2014]
FROM
(SELECT [SirName] + '' - '' + [SecondName] AS Name
,qry_Date.RoomNumber
,qry_Date.Date
FROM Guest RIGHT JOIN qry_Date ON Guest.ID = qry_Date.GuestID
WHERE qry_Date.RoomNumber Is Not Null) as t
PIVOT
(count(Name) FOR [Date] IN( [01/12/2014],[02/12/2014],[03/12/2014],[04/12/2014],[05/12/2014],[06/12/2014],[07/12/2014],[08/12/2014],[09/12/2014],[10/12/2014],[11/12/2014],[12/12/2014],[13/12/2014],[14/12/2014],[15/12/2014],[16/12/2014],[17/12/2014],[18/12/2014],[19/12/2014],[20/12/2014],[21/12/2014],[22/12/2014],[23/12/2014],[24/12/2014],[25/12/2014],[26/12/2014],[27/12/2014],[28/12/2014],[29/12/2014],[30/12/2014],[31/12/2014])
) as p

One quick way to deal with this error is to convert all data to varchar(max) in same manner. After all dates will become header, so it should be string.
DECLARE #cols AS NVARCHAR(MAX)
DECLARE #query AS VARCHAR(MAX)
SELECT #cols = STUFF((SELECT distinct top 100 percent
',' + QUOTENAME(CAST(qry_Date.Date AS NVARCHAR(MAX)))
FROM qry_Date
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)'),1,1,'');
SET #query = 'SELECT RoomNumber, ' + #cols + '
FROM
(SELECT [SirName] + '' - '' + [SecondName] AS Name
,qry_Date.RoomNumber
,CAST(qry_Date.Date AS NVARCHAR(MAX)) as [Date]
FROM Guest RIGHT JOIN qry_DateTemp ON Guest.ID = qry_Date.GuestID
WHERE qry_Date.RoomNumber Is Not Null) as t
PIVOT
(count(Name) FOR [Date] IN( ' + #cols + ')
) as p'
print #query
execute(#query)

#DhruvJoshi did it as u Proposed and true i was in error. when i got my results i had to change the query to
DECLARE #cols AS NVARCHAR(MAX)
DECLARE #query AS VARCHAR(MAX)
SELECT #cols = STUFF((SELECT distinct top 100 percent
',' + QUOTENAME(CAST(qry_Date.Date AS NVARCHAR(MAX)))
FROM qry_Date
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)'),1,1,'');
SET #query = 'SELECT RoomNumber, ' + #cols + '
FROM
(SELECT [SirName] + '' - '' + [SecondName] AS Names
,qry_Date.RoomNumber
,CAST(qry_Date.Date AS NVARCHAR(MAX)) as [Date]
FROM Guest RIGHT JOIN qry_Date ON Guest.ID = qry_Date.GuestID
WHERE qry_Date.RoomNumber Is Not Null) as t
PIVOT
(MAX([Names]) FOR [Date] IN( ' + #cols + ')
) as p'
print #query
execute(#query)

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;

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;

How To Set NULL is 0 in SQL Dynamic Pivot Query

I developed one dynamic pivot table, and I set ISNULL = 0.00.
The query is given below
SELECT DISTINCT hdr.EmpNo,hdr.FirstName AS Name,
ISNULL(TBL.shortname,'')AS shortname,
ISNULL(TBL.Amount,0.00) AS Amount,
TBL.Adtype INTO #Temp FROM tbl1 AS hdr
LEFT JOIN tbl2 TBL ON TBL.EmpNo = hdr.EmpNo
DECLARE #Ded AS NVARCHAR(MAX)
SET #Ded = STUFF((SELECT ', ISNULL( ' + QUOTENAME(c.shortname) + ', 0.00 )AS ' +
QUOTENAME(c.shortname) FROM (SELECT DISTINCT shortname FROM #Temp
WHERE ISNULL(shortname,'') <> '' AND Adtype = 2) AS c ORDER BY
shortname FOR XML PATH(''), TYPE ).value('.', 'NVARCHAR(MAX)')
,1,1,'')
SET #Query = 'SELECT CAST(ROW_NUMBER() OVER(ORDER BY EmpNo ASC) AS
VARCHAR(100)) AS [S.No],EmpNo,Name,' + #Ded +' FROM #Temp
PIVOT(SUM(Amount) FOR shortname IN (' + #Ded + ')) AS PVTTable'
EXEC sp_executesql #Query
But it displays the following error, and line 3 doesn't not have a "(".
Msg 102, Level 15, State 1, Line 3
Incorrect syntax near '('.
Any help to solve this problem would be appreciated.
Problem is with #der variable use in in clause.
you are setting column name with isnull and in in clause, it is not supported.
Please try below query.
;with tbl1 as
(
select 1 EmpNo,'Emp1' FirstName
union all
select 2 EmpNo,'Emp2' FirstName
),
tbl2 as
(
select 'EMP1' shortname,100 Amount, 2 Adtype,1 EmpNo
union all
select 'EMP2' shortname,100 Amount, 2 Adtype,2 EmpNo
)
SELECT DISTINCT hdr.EmpNo,hdr.FirstName AS Name,
ISNULL(TBL.shortname,'')AS shortname,
ISNULL(TBL.Amount,0.00) AS Amount,
TBL.Adtype INTO #Temp FROM tbl1 AS hdr
LEFT JOIN tbl2 TBL ON TBL.EmpNo = hdr.EmpNo
DECLARE #Ded AS NVARCHAR(MAX)='' ,#Query AS NVARCHAR(MAX)=''
DECLARE #Wer AS NVARCHAR(MAX)=''
SET #Ded = STUFF((SELECT ', ISNULL( ' + QUOTENAME(c.shortname) + ', 0.00 )AS ' +
QUOTENAME(c.shortname) FROM (SELECT DISTINCT shortname FROM #Temp
WHERE ISNULL(shortname,'') <> '' AND Adtype = 2) AS c ORDER BY
shortname FOR XML PATH(''), TYPE ).value('.', 'NVARCHAR(MAX)')
,1,1,'')
SET #Wer = STUFF((SELECT ', ' + QUOTENAME(c.shortname) FROM (SELECT DISTINCT shortname FROM #Temp
WHERE ISNULL(shortname,'') <> '' AND Adtype = 2) AS c ORDER BY
shortname FOR XML PATH(''), TYPE ).value('.', 'NVARCHAR(MAX)')
,1,1,'')
SET #Query = 'SELECT CAST(ROW_NUMBER() OVER(ORDER BY EmpNo ASC) AS
VARCHAR(100)) AS [S.No],EmpNo,Name,' + #Ded +' FROM #Temp
PIVOT(SUM(Amount) FOR shortname IN (' + #Wer + ')) AS PVTTable'
--print #Query
EXEC sp_executesql #Query

Writing my result as horizontal as String

Can someone help me how I can rewrite this query to get following result.
1 2 3 4 5
U.T A.H E.Z R.Z S.A
Sometimes it will return more or less than 5 results.
My query:
SELECT
LEFT(a.Vorname, 1) + '.' + LEFT(a.Name, 1) AS Name
FROM
ADR_Adressen a
LEFT JOIN
ADR_GruppenLink gl ON gl.AdressNrADR = a.AdressNrADR
WHERE
a.Z_Klasse = 'BA' AND gl.GruppeADR != 'KIND'
this could help you, using ROW_NUMBER()
DECLARE #cols AS NVARCHAR(MAX)
SELECT #cols = STUFF((SELECT ',[' + convert(varchar,ROW_NUMBER() OVER ( ORDER BY LEFT(a.[Name],1) ) )+ ']' AS ID
FROM [ADR_Adressen] a
FOR XML PATH(''), TYPE).value('.', 'varchar(max)'),1,1, '')
DECLARE #query AS NVARCHAR(MAX);
SET #query = N'SELECT ' + #cols + N' from
(
SELECT ROW_NUMBER() OVER ( ORDER BY LEFT(a.Name,1) ) AS ID,
LEFT(vorname,1) + ''.'' + LEFT(Name,1) Name
from ADR_Adressen a
LEFT JOIN ADR_GruppenLink gl ON gl.AdressNrADR = a.AdressNrADR
WHERE a.Z_Klasse = 'BA' AND gl.GruppeADR != 'KIND'
) x
pivot
(
max(Name)
for ID in (' + #cols + N')
) p
'
exec sp_executesql #query;
There's no pretty way to do this, if the number of rows is variable.
Building heavily on the answer to this question, you need to dynamically build the query before executing it.
DECLARE #cols AS NVARCHAR(MAX),
#query AS NVARCHAR(MAX)
-- Build a list of ids for each of the selected rows
SELECT #cols = STUFF((SELECT ',[' + convert(varchar,ROW_NUMBER() OVER ( ORDER BY LEFT([vorname],1),LEFT([Name],1) ) ) + ']'
FROM #ADR_Adressen
LEFT JOIN ADR_GruppenLink gl ON gl.AdressNrADR = a.AdressNrADR
WHERE a.Z_Klasse = 'BA' AND gl.GruppeADR != 'KIND'
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
-- Build a query using the list of IDs selected above. These are pivotted into column names
set #query = N'SELECT ' + #cols + N' from
(
select
ROW_NUMBER() OVER ( ORDER BY LEFT([vorname],1),LEFT([Name],1) ) ID,
LEFT(vorname,1) + ''.'' + LEFT(Name,1) Name
from #ADR_Adressen a
LEFT JOIN ADR_GruppenLink gl ON gl.AdressNrADR = a.AdressNrADR
WHERE a.Z_Klasse = 'BA' AND gl.GruppeADR != 'KIND'
) x
pivot
(
max(Name)
for ID in (' + #cols + N')
) p
'
exec sp_executesql #query;
Updated: Given that no ID field is available I've updated this to incorporate the ROW_NUMBER suggestion from Alex below
Query example

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!