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
Related
I need to Pivot Questions With Their Answers.The Desired Output of the pivot Query is below and the table structure too.
I have Created the SQL fiddle Here Sql Fiddle. I saw many examples of count with pivot but couldn't find something similar to this.
You simply need some joins to get the base data and a dynamic pivot to show the result in the desired format.
try the following:
drop table if exists #temp
--base table with all details
select s.ID SurveyID, s.SubmittedBy, sq.Question, sa.Answer
into #temp
from #Survey s
join #SurveyMaster sm on sm.ID = s.SurveyMasterID
join #SurveyQuestion sq on sq.SurveyMasterID = s.SurveyMasterID
join #SurveyAnswers sa on sa.SurveyQuestionID = sq.ID and sa.SurveyID = s.ID
--dynamic pivot
DECLARE #cols AS NVARCHAR(MAX),
#query AS NVARCHAR(MAX);
select #cols = STUFF((SELECT distinct ',' + QUOTENAME(c.Question)
FROM #temp c
ORDER BY 1 DESC
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set #query = 'SELECT SurveyID, SubmittedBy, ' + #cols + ' from
(
select SurveyID, SubmittedBy, Question, Answer
from #temp
) x
pivot
(
max(Answer)
for Question in (' + #cols + ')
) p '
--execution
execute(#query)
Please find the db<>fiddle here.
declare #sqlstring as varchar(max) = '';
SELECT
#sqlstring = STUFF((
SELECT distinct
',' + '[' + isnull(sq.Question, '''') + ']'
from
#surveyanswers sa
join
#SurveyQuestion sq
on sq.ID = sa.SurveyQuestionID
join
#survey sv
on sv.SurveyMasterID = sq.SurveyMasterID FOR XML PATH('')), 1, 1, '')
select
sa.SurveyID,
sv.SubmittedBy,
sq.Question,
sa.Answer into ##temp
from
#surveyanswers sa
join
#SurveyQuestion sq
on sq.ID = sa.SurveyQuestionID
join
#survey sv
on sv.SurveyMasterID = sq.SurveyMasterID
set
#sqlstring = 'SELECT SurveyID,SubmittedBy,' + #sqlstring + ' FROM (select * from ##temp ) t ' + ' PIVOT ( ' + ' max(Answer) FOR Question IN (' + #sqlstring + ' ) ) AS pivot_table' execute(#sqlstring);
RESULT:
I am joining 3 tables, Category, Value, NewFill:
SELECT
SaricasaNewFill.value AS 'Selected Values',
SaricasaCategory.description AS 'Category'
FROM
dbo.SaricasaValue
INNER JOIN
dbo.SaricasaNewFill ON SaricasaValue.value = SaricasaNewFill.value
INNER JOIN
dbo.SaricasaCategory ON SaricasaValue.cat_id = SaricasaCategory.cat_id
This is the result:
Now I have created a dynamic pivot when I can make the SaricasaCategory.description as 'Category' as my column header. But I do have a problem displaying multiple values. The query I created just display's that last value the SaricasaNewFill.value as 'Selected Values'
Here is the result of my pivot:
This is the query I wrote:
DECLARE #cols AS varchar(max), #qry AS varchar(max);
SELECT #cols = STUFF((SELECT DISTINCT ',' + QUOTENAME(c.description)
FROM dbo.SaricasaValue v
INNER JOIN dbo.SaricasaNewFill n ON v.value = n.value
INNER JOIN dbo.SaricasaCategory c ON v.cat_id = c.cat_id
FOR XML PATH(''), TYPE).value('.', 'varchar(max)'), 1, 1, '')
SET #qry = 'SELECT ' + #cols + 'FROM (SELECT n.value, c.description
FROM dbo.SaricasaValue v
INNER JOIN dbo.SaricasaNewFill n ON v.value = n.value
INNER JOIN dbo.SaricasaCategory c ON v.cat_id = c.cat_id) x
PIVOT
(MIN(value) FOR description IN (' + #cols + ')) p'
EXECUTE(#qry)
Is something missing is my query? I hope someone helps! Thank you!
Considering you need to show output in comma separated value.
DECLARE #cols as varchar(max), #qry as varchar(max);
select #cols = stuff ((select DISTINCT ',' + QUOTENAME(c.description)
FROM dbo.SaricasaValue v INNER JOIN dbo.SaricasaNewFill n ON v.value = n.value
INNER JOIN dbo.SaricasaCategory c ON v.cat_id = c.cat_id
for XML PATH(''), TYPE).value('.','varchar(max)'),1,1,'')
SELECT n.value ,c.description into #saricasa
FROM dbo.SaricasaValue v INNER JOIN dbo.SaricasaNewFill n ON v.value = n.value
INNER JOIN dbo.SaricasaCategory c ON v.cat_id = c.cat_id
set #qry = 'select ' + #cols + 'from(SELECT description,stuff ((select DISTINCT '','' + c.value
FROM #saricasa c where d.description=c.description
for XML PATH(''''), TYPE).value(''.'',''varchar(max)''),1,1,'''') as value
from #saricasa d
) x
pivot
(min(value) for description in (' + #cols + ')) p'
EXECUTE(#qry)
I suggest you change varchar(max) to nvarchar(max)
prevent Unicode problem,And your 'from' should add space ' from'
DECLARE #cols as nvarchar(max), #qry as nvarchar(max);
select #cols = stuff ((select DISTINCT ',' + QUOTENAME(c.description)
FROM dbo.SaricasaValue v INNER JOIN dbo.SaricasaNewFill n ON v.value = n.value
INNER JOIN dbo.SaricasaCategory c ON v.cat_id = c.cat_id
for XML PATH(''), TYPE).value('.','varchar(max)'),1,1,'')
set #qry = N'select ' + #cols + N' from(SELECT n.value ,c.description
FROM dbo.SaricasaValue v INNER JOIN dbo.SaricasaNewFill n ON v.value = n.value
INNER JOIN dbo.SaricasaCategory c ON v.cat_id = c.cat_id
) x
pivot
(min(value) for description in (' + #cols + N')) p'
EXECUTE(#qry)
I was able to display every row in column using pivot however when there are multiple values, it displays only one of the row values. My suspicion lies on the MAX function in the for loop, however, have not been able to find a successful replacement.
I've tried other SQL functions.
DECLARE #cols AS NVARCHAR(MAX),
#query AS NVARCHAR(MAX)
SELECT #cols = STUFF((SELECT ',' + QUOTENAME(Provincia)
FROM Codigos_Postales
GROUP BY Provincia
ORDER BY Provincia
FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'), 1, 1, '')
SET #query = N'SELECT Poblacion,' + #cols + N' from
(
select * from Codigos_Postales
) x
pivot
(
MAX(Codigo_Postal)
for Provincia in (' + #cols + N')
) p ORDER BY Poblacion ASC'
EXEC sp_executesql #query;
Table I'm trying to pivot:
Result:
Expected Result:
If I understand corerctly, adding ROW_NUMBER to your source data will do the trick. The sample PIVOT script will be as below. Just ignore the RN column from your final output, that's it.
SET #query =
N'SELECT Poblacion,' + #cols + N' from
(
SELECT
ROW_NUMBER() OVER (ORDER BY Provincia) RN,
*
FROM Codigos_Postales
) x
PIVOT
(
MAX(Codigo_Postal)
FOR Provincia IN (' + #cols + N')
) p ORDER BY Poblacion ASC'
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
To avoid "ORDER BY items must appear in the select list if SELECT DISTINCT is specified.", I need to add AssessmentSuperSet.Deadline to my SELECT statement at the top. Where should I do this? Any help greatly appreciated. Thanks.
DECLARE #cols AS NVARCHAR(MAX),
#query AS NVARCHAR(MAX)
select #cols = STUFF(
(SELECT distinct ',' + QUOTENAME(AssessmentSuperSet.Title)
from AssessmentSuperSet inner join AssessmentSet on AssessmentSuperSet.SuperSetID = AssessmentSet.SuperSetID
where ClassID = '8KF/En 14/15' order by AssessmentSuperSet.Deadline ASC
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set #query = 'SELECT StudentID, FName, SName, ' + #cols + ' from
(
select KS3Assessments.StudentID,
Pupils.FName,
Pupils.SName,
KS3Assessments.NCLevel,
AssessmentSuperSet.Title
from KS3Assessments inner join Pupils on KS3Assessments.StudentID = Pupils.StudentID
inner join AssessmentSuperSet on KS3Assessments.SuperSetID = AssessmentSuperSet.SuperSetID
where Pupils.GroupDesignation = ''8KF/En 14/15''
) x
pivot (max(NCLevel) for Title in (' + #cols + ') ) p '
execute(#query)
Instead of distinct try using a group by clause:
select #cols = STUFF(
(SELECT ',' + QUOTENAME(AssessmentSuperSet.Title)
from AssessmentSuperSet inner join AssessmentSet on AssessmentSuperSet.SuperSetID = AssessmentSet.SuperSetID
where ClassID = '8KF/En 14/15'
group by AssessmentSuperSet.title, AssessmentSuperSet.Deadline
order by AssessmentSuperSet.Deadline ASC
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set #query = 'SELECT StudentID, FName, SName, ' + #cols + ' from
(
select KS3Assessments.StudentID,
Pupils.FName,
Pupils.SName,
KS3Assessments.NCLevel,
AssessmentSuperSet.Title
from KS3Assessments inner join Pupils on KS3Assessments.StudentID = Pupils.StudentID
inner join AssessmentSuperSet on KS3Assessments.SuperSetID = AssessmentSuperSet.SuperSetID
where Pupils.GroupDesignation = ''8KF/En 14/15''
) x
pivot (max(NCLevel) for Title in (' + #cols + ') ) p '
execute(#query)
Since you didn't provide any suitable test data I haven't tried it.