虽然开发过程中没用过行列转换,但是听说面试时常常会遇到这个问题,以前在网上也看到过大神的例子,今天自己仔细的玩了下,希望和大家分享一下了。
注意:列转行的方法可能是我独创的了,呵呵,因为在网上找不到哦,全部是我自己写的,用到了系统的SysColumns
(一)行转列的方法
先说说行转列的方法,这个就比较好想了,利用拼sql和case when解决即可
实现目的
1:建立测试用的数据库
CREATE TABLE RowTest(
[Name] [nvarchar](
10
) NULL,--
名稱
[Course] [nvarchar](
10
) NULL,--
課程名稱
[Record] [
int
] NULL--
課程的分數
)
2:加入测试用的数据库(先加入整齐的数据)
insert into RowTest values (
'
张三
'
,
'
语文
'
,
'
91
'
)
insert into RowTest values (
'
张三
'
,
'
数学
'
,
'
92
'
)
insert into RowTest values (
'
张三
'
,
'
英语
'
,
'
93
'
)
insert into RowTest values (
'
张三
'
,
'
生物
'
,
'
94
'
)
insert into RowTest values (
'
张三
'
,
'
物理
'
,
'
95
'
)
insert into RowTest values (
'
张三
'
,
'
化学
'
,
'
96
'
)
insert into RowTest values (
'
李四
'
,
'
语文
'
,
'
81
'
)
insert into RowTest values (
'
李四
'
,
'
数学
'
,
'
82
'
)
insert into RowTest values (
'
李四
'
,
'
英语
'
,
'
83
'
)
insert into RowTest values (
'
李四
'
,
'
生物
'
,
'
84
'
)
insert into RowTest values (
'
李四
'
,
'
物理
'
,
'
85
'
)
insert into RowTest values (
'
李四
'
,
'
化学
'
,
'
86
'
)
insert into RowTest values (
'
小生
'
,
'
语文
'
,
'
71
'
)
insert into RowTest values (
'
小生
'
,
'
数学
'
,
'
72
'
)
insert into RowTest values (
'
小生
'
,
'
英语
'
,
'
73
'
)
insert into RowTest values (
'
小生
'
,
'
生物
'
,
'
74
'
)
insert into RowTest values (
'
小生
'
,
'
物理
'
,
'
75
'
)
insert into RowTest values (
'
小生
'
,
'
化学
'
,
'
76
'
)
3:设计想法
行转列的原理就是把行的类别找出来当做查询的字段,利用case when 把当前的分数加到当前的字段上去,最后用group by 把数据整合在一起
4:通用方法
declare
@sql
nvarchar
(
max
)
set
@sql
=
'
select Name
'
select
@sql
=
@sql
+
'
,
'
+
'
isnull(max( case when Course=
'''
+
TCourse.Course
+
'''
then Record end ),0)
'
+
TCourse.Course
from
(
select
distinct
Course
from
RowTest)TCourse
set
@sql
=
@sql
+
'
from RowTest group by Name order by Name
'
print
@sql
exec
(
@sql
)
说明: 把所有的课程名称取出来作为列(查询表TCourse)
用case when 的方法把sql 拼出来
5:课外试验
(1)加入数据
insert into dbo.RowTest values (
'
小生
'
,
'
生物
'
,
'
110
'
)
去除max 方法会报错,因为一条可能对应多行数据
(2)加入数据
insert into dbo.RowTest values (
'
小生
'
,
'
計算機
'
,
'
110
'
)
数据会多出一列,但是其他人无此课程就会为0
至此,数据行转列ok
(二)列转行的新方法开始了
实现目的
1:实现原理
在网上看了别人的做法,基本都是用union all 来一个个转换的,我觉得不太好用。
首先我想到了要把所有的列名取出来,就在网上查了下获取表的所有列名
然后我可以把主表和列名形成的表串起来,这样就可以形成需要的列数,然后根据判断取值就完成了了,呵呵
2:建立表格
create
table
CoulumTest
(
Name
nvarchar
(
10
),
语文
int
,
数学
int
,
英语
int
)
3:加入数据
insert into CoulumTest values(N
'
张三
'
,
90
,
91
,
92
)
insert into CoulumTest values(N
'
李四
'
,
80
,
81
,
82
)
4:经典的地方来了
select
CT.Name,Col.name 课程,
(
case
when
Col.name
=
N
'
语文
'
then
CT.语文
when
Col.name
=
N
'
数学
'
then
CT.数学
when
Col.name
=
N
'
英语
'
then
CT.英语
end
)
as
分数
from
CoulumTest CT
left
join
(
select
name
from
SysColumns
Where
id
=
Object_Id
(
'
CoulumTest
'
)) Col
on
Col.name
<>
'
Name
'
你没看错,一句话搞定,但是有个问题迷惑了我,我觉得还不够简化,如果可以把case when 都不用了就更好了,请大神们指点小弟一下了。怎么根据
Col的name 直接取得分数

