Table Student:
Studid StuName
=========================
1 'Marco Polo'
2 'Leroy Jenkins'
Table Subjects:
Subid SubName
===================
1 English
2 French
3 German
4 Math
5 Physics
Table Grades
Stuid Subid Grade1 Grade2
==================================================
1 1 10 6
1 2 9 7
2 1 8 4
2 4 7 9
2 5 6 10
I would like to achieve 2 tables: Table1:
StuName English 1 English 2 French 1 French 2
==================================================================
'Marco Polo' 10 6 9 7
Table1:
StuName English 1 English 2 Math 1 Math 2 Physics 1 Physics 2
==================================================================
'Leroy Jenkins' 8 4 7 9 6 10
In your example the id on Student
is StudId
and in Grades
it is StuId
. This may or may not be a typo, but I left it as posted.
You need to unpivot
the subject+gradenumber (I use the cross apply(values... )
method to unpivot
in the code below but a union all
or unpivot()
version would work as well), and then pivot.
Since you only want to return columns specific to each student, you use a filter on the column list generation and in the inner query of the pivot
and pass that parameter to sp_executesql
for the execution of the generated code.
declare @cols nvarchar(max), @sql nvarchar(max), @StuId int;
set @StuId = 2;
set @cols = stuff((
select ', ' + quotename(sub.subName+'1')+', '+ quotename(sub.subName+'2')
from Grades g
inner join Student stu
on g.StuId = stu.StudId
inner join Subjects sub
on g.SubId = sub.SubId
where stu.StudId = @StuId
order by 1
for xml path (''), type).value('(./text())[1]','nvarchar(max)')
,1,2,'');
set @sql = '
select StuName, '+ @cols +'
from (
select stu.StuName, u.SubName, u.Grade
from Grades g
inner join Student stu
on g.StuId = stu.StudId
inner join Subjects sub
on g.SubId = sub.SubId
cross apply (values
(sub.SubName+''1'', g.Grade1)
, (sub.SubName+''2'', g.Grade2)
)u (SubName,Grade)
where stu.StudId = @StuId
) as t
pivot (sum(Grade) for SubName in (' + @cols +')) p';
select CodeGenerated = @sql;
exec sp_executesql @sql ,N'@StuId int', @StuId;
rextester demo: http://rextester.com/DCLY81531
returns CodeGenerated
:
select StuName, [English1], [English2], [Math1], [Math2], [Physics1], [Physics2]
from (
select stu.StuName, u.SubName, u.Grade
from Grades g
inner join Student stu
on g.StuId = stu.StudId
inner join Subjects sub
on g.SubId = sub.SubId
cross apply (values
(sub.SubName+'1', g.Grade1)
, (sub.SubName+'2', g.Grade2)
)u (SubName,Grade)
where stu.StudId = @StuId
) as t
pivot (sum(Grade) for SubName in ([English1], [English2], [Math1], [Math2], [Physics1], [Physics2])) p
for @StuId = 2
returns:
+---------------+----------+----------+-------+-------+----------+----------+
| StuName | English1 | English2 | Math1 | Math2 | Physics1 | Physics2 |
+---------------+----------+----------+-------+-------+----------+----------+
| Leroy Jenkins | 8 | 4 | 7 | 9 | 6 | 10 |
+---------------+----------+----------+-------+-------+----------+----------+
for @StuId = 1
returns:
+------------+----------+----------+---------+---------+
| StuName | English1 | English2 | French1 | French2 |
+------------+----------+----------+---------+---------+
| Marco Polo | 10 | 6 | 9 | 7 |
+------------+----------+----------+---------+---------+
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.