不显示列名称

时间:2013-09-27 16:37:12

标签: sql sql-server sql-server-2008 tsql unpivot

我有一个表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 个答案:

答案 0 :(得分:177)

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

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

请参阅SQL Fiddle with demo

答案 1 :(得分:7)

您也可以使用以下代码的逻辑序列来尝试标准的sql un-pivoting方法。 以下代码包含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;
    

答案 2 :(得分:0)

选择*来自学生

UNPIVOT(在(数学,科学,英语)课程中为科目标记);

答案 3 :(得分:0)

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

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