使用列名取消数据透视

我有一个 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

使用 重新转向,我能够正确地获得 Name,Marks,但是不能够获得源表中的列名到所需结果集中的 Subject列。

我怎么才能做到呢?

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

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


) as UnPvt
321238 次浏览

你的问题很接近了。您应该能够使用以下内容,其中包括最终选择列表中的 subject:

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

参见 带演示的 SQL Fiddle

您还可以尝试使用标准的 sql unpivoting 方法,方法是使用以下代码的逻辑序列。 以下代码有三个步骤:

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

     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;
    

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

select name, Subject, Marks
from studentmarks
Cross Apply (
values (Maths,'Maths'),(Science,'Science'),(English,'English')
) un(Marks, Subject)
where marks is not null;