table行轉列的sql詳解

2021-04-29 23:37:09 字數 3391 閱讀 4387

tabele行轉列的資料,網上搜一下很多。大家照著網上copy就可以實現自己想要的功能。但是大家在實現功能後是否想過行轉列為什麼要這樣寫?下面就以乙個例項來分析, 希望對初學者有所幫助。

一、要求

1 建立資料表

create table [dbo].[stuscore](

[stuid] [int] not null,       

[subject] [nvarchar](30) null,

[score] [decimal](5, 1) null

) 2 插入測試資料

stuid   subject score

3    chinese    76.0

3    math    73.0

4    chinese    82.0

5    chinese    66.0

5    math    93.0

6    chinese    67.0

7    math    83.0

8    chinese    77.0

8    math    84.0

3 行轉列後的結果

stuid   chinese math

3    76.0    73.0

4    82.0    0.0

5    66.0    93.0

6    67.0    0.0

7    0.0    83.0

8    77.0    84.0

二 、分析

1 行轉列,乙個重點就是怎麼樣知道有多少列,怎麼樣建立這些列?我們可以先把這個問題擱置,而假設這些列是已知的。 例如示例資料中,可以先假設subject的資料[chinese,math]是已知的,這樣問題就簡化了許多

2 當已知了chinese,math後,我們至少要先得到轉換後的tabel結構

如下;select stuid, 0 as chinese, 0 as math from dbo.stuscore

結果如下

stuid   chinese math

3    0    0

3    0    0

4    0    0

5    0    0

5    0    0

6    0    0

7    0    0

8    0    0

8    0    0

3 接著就需要往這個資料集中去填充chinese, math的資料

select stuid,

case subject when 'chinese' then score else 0 end as chinese,

case subject when 'math' then score else 0 end as math

from dbo.stuscore

結果如下:

stuid   chinese math

3    76.0    0.0

3    0.0    73.0

4    82.0    0.0

5    66.0    0.0

5    0.0    93.0

6    67.0    0.0

7    0.0    83.0

8    77.0    0.0

8    0.0    84.0

4 細心的讀者會發現步驟3中的結果與我們想要的已經非常接近了,只需再做乙個sum()處理,就ok了

select stuid,

sum(case subject when 'chinese' then score else 0 end ) as chinese,

sum(case subject when 'math' then score else 0 end ) as math

from dbo.stuscore group by stuid

得到的正是我們想要的結果

stuid   chinese math

3    76.0    73.0

4    82.0    0.0

5    66.0    93.0

6    67.0    0.0

7    0.0    83.0

8    77.0    84.0

是不是現在就已經完成了呢?答案是否定的。前面我們已經說過,是為了簡化問題,在假設已經知道了subject資料的情況下,這麼處理的,實際上subject的資料是可變的,未知的,接下來就是要解決這個問題了

5 要獲取subject的資料其實很簡單

select distinct subject from dbo.stuscore

獲取以後怎樣得到case subject when 'chinese' then score else 0 end 這種語句?

可以根據subject的值去動態的組sql語句

看下面的一段**

declare @sql varchar(2000)

set @sql=''

select @sql =@sql+ ',case subject when '''+subject+''' then 1 else 0 end  as ' + subject

from (select distinct subject from dbo.stuscore) as sub

print @sql

message列印的資訊如下:

,case subject when 'chinese' then 1 else 0 end  as chinese,case subject when 'math' then 1 else 0 end  as math

6 最後我們就需要將前面步驟綜合起來,得到最終的sql

declare @sql varchar(2000)

set @sql='select stuid'

select @sql =@sql+ ',sum(case subject when '''+subject+''' then score else 0 end)  as ' + subject

from (select distinct subject from dbo.stuscore) as sub

set @sql=@sql + ' from dbo.stuscore group by stuid'

exec(@sql)

stuid   chinese math

3    76.0    73.0

4    82.0    0.0

5    66.0    93.0

6    67.0    0.0

7    0.0    83.0

8    77.0    84.0

至此,整個分析過程和結果就都出來了。

初試寫文章, 多包涵,指正。

sql的行轉列

在弄資料包表的時候,我們常常會用到這個需求。在mysql中行轉列 新建乙個表,學生名字,課程,分數 drop table if exists student create table student username varchar 20 subjects varchar 20 score int ...

sql 行轉列問題

題目 下表tproduct某產品在各城市各月銷量情況 city name month no 月 qut qty 臺 杭州 9 100 杭州 10 120 上海 9 130 上海 10 140 請寫sql實現 如下查詢 city 9月銷量 10月銷量 杭州 100 120 上海 130 140 答案一...

SQL 行轉列總結

行轉列應該使用case 想要把某個行轉成列的列名 when 裡將各個列的值放進去 then 分組後某個值要進行彙總行 else 0 end 動態生成的話,將想要用的轉的,用selec查出來拼成以上格式就可以了 declare sql varchar 8000 如果大於8000只能用程式去拼乙個sql...