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
不用枢纽,我能够正确获取名称,标记,但无法将源表中的列名称获取到所需结果集中的
Subject
列。如何实现?
到目前为止,我已经达到以下查询(获取名称,商标)
select Name, Marks from studentmarks
Unpivot
(
Marks for details in (Maths, Science, English)
) as UnPvt
#1 楼
您的查询非常接近。您应该能够使用以下内容,包括最终选择列表中的subject
:select u.name, u.subject, u.marks
from student s
unpivot
(
marks
for subject in (Maths, Science, English)
) u;
请参阅带有演示的SQL Fiddle
评论
@bluefeet有没有一种方法可以使您不需要指定名称(数学,科学,英语)?我正在对许多表执行此操作,这些表都具有相同的结构,但具有不同的列名。
– LBogaardt
17年2月8日在9:23
@LBogaardt不,您需要显式定义要包括的列。
– jjjjjjjjjjj
17年2月9日在15:32
@LBogaardt在这里看看我的答案,您可以使用动态sql取消透视,而无需指定列名。
– Taryn♦
17年2月9日在15:36
#2 楼
您还可以通过以下代码使用一系列逻辑来尝试标准sql取消透视方法。.以下代码包含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;
评论
这也适用于任何RDBMS!值(如果不可用)可用带有SELECT ... UNION ... SELECT的子查询替换。尽管想知道CROSS JOIN的性能...
– Cristi S.
18-10-16在20:39
#3 楼
使用交叉联接的另一种方法是在交叉联接内指定列名称。select name, Subject, Marks
from studentmarks
Cross Join (
values (Maths,'Maths'),(Science,'Science'),(English,'English')
) un(Marks, Subject)
where marks is not null;
#4 楼
选择*来自学生UNPIVOT(标记为(数学,科学,英语)科目的科目);
评论
这已经和将近6年前发布的广受好评的答案是一样的答案吗?
– ImaginaryHuman072889
19年7月10日在12:34
评论
您可以张贴您到目前为止所做的事情吗?查询/输出。