2017-07-07 30 views
0

表學生:T-SQL的動態透視不同和多列

Studid  StuName  
========================= 
1   'Marco Polo' 
2   'Leroy Jenkins' 

表主題:

Subid  SubName  
=================== 
1   English 
2   French 
3   German 
4   Math 
5   Physics 

表等級

Stuid  Subid   Grade1   Grade2 
================================================== 
1   1    10    6  
1   2    9    7  
2   1    8    4  
2   4    7    9  
2   5    6    10 

我想實現2個表: 表1:

StuName  English 1  English 2  French 1  French 2 
================================================================== 
'Marco Polo'  10    6    9    7 

表1:

StuName  English 1  English 2  Math 1  Math 2  Physics 1  Physics 2 
================================================================== 
'Leroy Jenkins' 8    4    7    9 6    10 
+1

的問題是,樂華是要趕在之前,你甚至寫完您的查詢。 – SqlZim

+0

關於你的預期結果應該是什麼不是很清楚。另外,你能否提供你迄今爲止所嘗試的? – gh0st

+0

我沒有嘗試任何事情,我不知道,因爲通知,字段的數量是一個時間5,另一個是7 – assmokey

回答

0

在您的例子在Student的ID是StudIdGrades這是StuId。這可能是也可能不是一個錯字,但是我把它作爲張貼留下。

您需要unpivot主題+ gradenumber(我用的是cross apply(values...)方法unpivot在下面的代碼,但一個union allunpivot()版本將工作爲好),然後轉動。

既然你只是想返回特定於每一個學生列,您使用的列列表生成,並在pivot的內部查詢的過濾器和參數傳遞給sp_executesql爲生成的代碼的執行。

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演示:http://rextester.com/DCLY81531

回報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 

@StuId = 2回報:

+---------------+----------+----------+-------+-------+----------+----------+ 
| StuName | English1 | English2 | Math1 | Math2 | Physics1 | Physics2 | 
+---------------+----------+----------+-------+-------+----------+----------+ 
| Leroy Jenkins |  8 |  4 |  7 |  9 |  6 |  10 | 
+---------------+----------+----------+-------+-------+----------+----------+ 

@StuId = 1回報:

+------------+----------+----------+---------+---------+ 
| StuName | English1 | English2 | French1 | French2 | 
+------------+----------+----------+---------+---------+ 
| Marco Polo |  10 |  6 |  9 |  7 | 
+------------+----------+----------+---------+---------+ 
+0

Studid是一個錯字,這是Stuid。 謝謝你的答案,標記爲正確的答案。 – assmokey

+0

@assmokey樂於助人! – SqlZim