136

我有一个StudentMarks带有列的表Name, Maths, Science, English。数据就像

Name,  Maths, Science, English  
Tilak, 90,    40,      60  
Raj,   30,    20,      10

我想把它安排如下:

Name,  Subject,  Marks
Tilak, Maths,    90
Tilak, Science,  40
Tilak, English,  60

使用unpivot我能够正确获取名称、标记,但无法将源表中的列名获取到Subject所需结果集中的列。

我怎样才能做到这一点?

到目前为止,我已经完成了以下查询(获取名称、标记)

select Name, Marks from studentmarks
Unpivot
(
  Marks for details in (Maths, Science, English)

) as UnPvt
4

3 回答 3

221

您的查询非常接近。您应该能够使用包含subject在最终选择列表中的以下内容:

select u.name, u.subject, u.marks
from student s
unpivot
(
  marks
  for subject in (Maths, Science, English)
) u;

请参阅带有演示的 SQL Fiddle

于 2013-09-27T16:48:39.573 回答
10

您也可以通过使用带有以下代码的一系列逻辑来尝试标准的 sql 反透视方法。以下代码有 3 个步骤:

  1. 使用交叉连接为每一行创建多个副本(在这种情况下也创建主题列)
  2. 创建列“标记”并使用案例表达式填写相关值(例如:如果主题是科学,则从科学列中选择值)
  3. 删除任何空组合(如果存在,如果基表中严格没有空值,则可以完全避免表表达式)

     select *
     from 
     (
        select name, subject,
        case subject
        when 'Maths' then maths
        when 'Science' then science
        when 'English' then english
        end as Marks
    from studentmarks
    Cross Join (values('Maths'),('Science'),('English')) AS Subjct(Subject)
    )as D
    where marks is not null;
    
于 2018-02-23T21:51:15.040 回答
1

使用交叉连接的另一种方法是在交叉连接中指定列名

select name, Subject, Marks 
from studentmarks
Cross Join (
values (Maths,'Maths'),(Science,'Science'),(English,'English')
) un(Marks, Subject)
where marks is not null;
于 2019-11-01T02:46:06.447 回答