雖然開發(fā)過程中沒用過行列轉(zhuǎn)換,但是聽說面試時常常會遇到這個問題,以前在網(wǎng)上也看到過大神的例子,今天自己仔細的玩了下,希望和大家分享一下了。
注意:列轉(zhuǎn)行的方法可能是我獨創(chuàng)的了,呵呵,因為在網(wǎng)上找不到哦,全部是我自己寫的,用到了系統(tǒng)的SysColumns
(一)行轉(zhuǎn)列的方法
先說說行轉(zhuǎn)列的方法,這個就比較好想了,利用拼sql和case when解決即可
實現(xiàn)目的
1:建立測試用的數(shù)據(jù)庫
CREATE TABLE RowTest(
[Name] [nvarchar](
10
) NULL,--
名稱
[Course] [nvarchar](
10
) NULL,--
課程名稱
[Record] [
int
] NULL--
課程的分?jǐn)?shù)
)
2:加入測試用的數(shù)據(jù)庫(先加入整齊的數(shù)據(jù))
insert into RowTest values (
'
張三
'
,
'
語文
'
,
'
91
'
)
insert into RowTest values (
'
張三
'
,
'
數(shù)學(xué)
'
,
'
92
'
)
insert into RowTest values (
'
張三
'
,
'
英語
'
,
'
93
'
)
insert into RowTest values (
'
張三
'
,
'
生物
'
,
'
94
'
)
insert into RowTest values (
'
張三
'
,
'
物理
'
,
'
95
'
)
insert into RowTest values (
'
張三
'
,
'
化學(xué)
'
,
'
96
'
)
insert into RowTest values (
'
李四
'
,
'
語文
'
,
'
81
'
)
insert into RowTest values (
'
李四
'
,
'
數(shù)學(xué)
'
,
'
82
'
)
insert into RowTest values (
'
李四
'
,
'
英語
'
,
'
83
'
)
insert into RowTest values (
'
李四
'
,
'
生物
'
,
'
84
'
)
insert into RowTest values (
'
李四
'
,
'
物理
'
,
'
85
'
)
insert into RowTest values (
'
李四
'
,
'
化學(xué)
'
,
'
86
'
)
insert into RowTest values (
'
小生
'
,
'
語文
'
,
'
71
'
)
insert into RowTest values (
'
小生
'
,
'
數(shù)學(xué)
'
,
'
72
'
)
insert into RowTest values (
'
小生
'
,
'
英語
'
,
'
73
'
)
insert into RowTest values (
'
小生
'
,
'
生物
'
,
'
74
'
)
insert into RowTest values (
'
小生
'
,
'
物理
'
,
'
75
'
)
insert into RowTest values (
'
小生
'
,
'
化學(xué)
'
,
'
76
'
)
3:設(shè)計想法
? 行轉(zhuǎn)列的原理就是把行的類別找出來當(dāng)做查詢的字段,利用case when 把當(dāng)前的分?jǐn)?shù)加到當(dāng)前的字段上去,最后用group by 把數(shù)據(jù)整合在一起
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)加入數(shù)據(jù)
insert into dbo.RowTest values (
'
小生
'
,
'
生物
'
,
'
110
'
)
去除max 方法會報錯,因為一條可能對應(yīng)多行數(shù)據(jù)
(2)加入數(shù)據(jù)
insert into dbo.RowTest values (
'
小生
'
,
'
計算機
'
,
'
110
'
)
數(shù)據(jù)會多出一列,但是其他人無此課程就會為0
至此,數(shù)據(jù)行轉(zhuǎn)列ok?
(二)列轉(zhuǎn)行的新方法開始了
實現(xiàn)目的
?
1:實現(xiàn)原理
在網(wǎng)上看了別人的做法,基本都是用union all 來一個個轉(zhuǎn)換的,我覺得不太好用。
首先我想到了要把所有的列名取出來,就在網(wǎng)上查了下獲取表的所有列名
?然后我可以把主表和列名形成的表串起來,這樣就可以形成需要的列數(shù),然后根據(jù)判斷取值就完成了了,呵呵
2:建立表格
create
table
CoulumTest
(
Name
nvarchar
(
10
),
語文
int
,
數(shù)學(xué)
int
,
英語
int
)
3:加入數(shù)據(jù)
insert into CoulumTest values(N
'
張三
'
,
90
,
91
,
92
)
insert into CoulumTest values(N
'
李四
'
,
80
,
81
,
82
)
4:經(jīng)典的地方來了
select
CT.Name,Col.name 課程,
(
case
when
Col.name
=
N
'
語文
'
then
CT.語文
when
Col.name
=
N
'
數(shù)學(xué)
'
then
CT.數(shù)學(xué)
when
Col.name
=
N
'
英語
'
then
CT.英語
end
)
as
分?jǐn)?shù)
from
CoulumTest CT
left
join
(
select
name
from
SysColumns
Where
id
=
Object_Id
(
'
CoulumTest
'
)) Col
on
Col.name
<>
'
Name
'
你沒看錯,一句話搞定,但是有個問題迷惑了我,我覺得還不夠簡化,如果可以把case when 都不用了就更好了,請大神們指點小弟一下了。怎么根據(jù)
Col的name 直接取得分?jǐn)?shù)
?
更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主
微信掃碼或搜索:z360901061
微信掃一掃加我為好友
QQ號聯(lián)系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元

