【问题标题】:T-SQL Dynamic Pivot on different and multiple columns不同列和多列上的 T-SQL 动态枢轴
【发布时间】:2017-12-12 01:06:14
【问题描述】:

表学生:

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

【问题讨论】:

  • 问题是 Leroy 会在你写完查询之前冲进来。
  • 您的预期结果应该是什么还不是很清楚。另外,你能提供你迄今为止尝试过的东西吗?
  • 我什么都没尝试,我不知道,因为请注意字段数一次是 5,另一个是 7。

标签: sql sql-server-2008 tsql pivot


【解决方案1】:

在您的示例中,Student 上的 id 是 StudIdGrades 上是 StuId。这可能是也可能不是错字,但我将其保留为已发布。

您需要unpivot 主题+年级编号(我在下面的代码中使用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 |
+------------+----------+----------+---------+---------+

【讨论】:

  • Stuid 是一个错字,是Stuid。谢谢你的回答,标记为正确的。
  • @assmokey 乐于助人!
猜你喜欢
  • 2012-09-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-28
  • 1970-01-01
  • 2011-04-26
相关资源
最近更新 更多