經典SQL問題 行轉列,列轉行

2021-09-07 04:52:07 字數 4097 閱讀 4605

情景簡介

學校裡面記錄成績,每個人的選課不一樣,而且以後會新增課程,所以不需要把所有課程當作列。資料庫grade裡面資料如下圖,假定每個人姓名都不一樣,作為主鍵。本文以mysql為基礎,其他資料庫會有些許語法不同。

資料庫資料:

mysql>

select

*from

grade;+--

----+--------+--------+-------+

| id | name | course | score |+--

----+--------+--------+-------+|1

| 張三 | 語文 |80|

|2| 張三 | 數學 |90|

|3| 張三 | 英語 |90|

|4| 李四 | 語文 |47|

|5| 李四 | 數學 |78|

|6| 王五 | 數學 |97|

+------+--------+--------+-------+

6 rows in

set (0.00

sec)

mysql

>

處理後效果:

+

--------+--------+--------+--------+

| name | 語文 | 數學 | 英語 |+--

------+--------+--------+--------+

| 張三 |80|

90|90|

| 李四 |47|

78|null

|| 王五 |

null|97

|null|+

--------+--------+--------+--------+

3 rows in

set (0.00

sec)

mysql

>

下面介紹三種方法:

方法一:

select

distinct

a.name,

(select score from grade b where a.name=b.name and b.course='語文

' ) as'語文

',(select score from grade b where a.name=b.name and b.course='數學

' ) as'數學

',(select score from grade b where a.name=b.name and b.course='英語

' ) as'英語

'from grade a

方法二:

select

name,

sum(case course when'語文

'then score end ) as'語文

',sum(case course when'數學

'then score end ) as'數學

',sum(case course when'英語

'then score end ) as'英語

'from grade group

by name

方法三:

delimiter &&

create

procedure

sp_count()

begin

#課程名稱

declare course_n varchar(20

);#所有課程數量

declare

count

int;

#計數器

declare i int

default0;

#拼接sql字串

set@s='

select name';

setcount

= (select

count(distinct course) from

grade);

while i <

count

doset course_n = (select course from grade limit i,1

);set

@s= concat(@s, '

, sum(case course when

','\

'', course_n,

'\'','

then score end )

','as

','\

'',course_n,

'\''

);set i = i+1;

endwhile

;set

@s= concat(@s, '

from grade group by name');

#用於除錯

#select@s;

prepare stmt from@s;

execute

stmt;

end&&

call sp_count();

方法分析:

第一種方法使用了表連線。

第二種使用了分組,對每個分組分別處理。

第三種使用了儲存過程,其實是第二種方法的動態化,先計算出所有課程的數量,然後對每個分組進行課程查詢。

很明顯前兩種方法屬於硬編碼,增加課程後就需要修改sql。而第三種則沒有這種問題。

note:

mysql中不能在乙個儲存過程中刪除另乙個儲存過程,只能呼叫另乙個儲存過程

本來想在方法三裡面寫上:drop procedure if exists sp_count();這是錯誤的。除錯的時候如果寫錯了,只能手動刪除了,也沒找到好方法。

結果轉出行或者乙個拼接字串:《

mysql函式之五:group_concat mysql 把結果集中的一列資料用指定分隔符轉換成一行

原來是這樣

名稱 單價 進貨價

記憶體 120 100

現在想這樣

名稱 **

記憶體 120

記憶體 100

mysql>

select

*from

device_info;+--

------+--------+-----------+

| dname | danjia | jinhuojia |+--

------+--------+-----------+

| 記憶體 |

100|80|

| cpu |

200|

150|

| 硬碟 |

300|

230|+--

------+--------+-----------+

3 rows in

set (0.00

sec)

mysql

>

sql:

mysql>

select

*from

-> (select dname, danjia as jiage from

device_info

->

union

all->

select dname,jinhuojia as jiage from device_info) as

temp

->

order

bydname;+--

------+-------+

| dname | jiage |+--

------+-------+

| cpu |

150|

| cpu |

200|

| 記憶體 |80|

| 記憶體 |

100|

| 硬碟 |

230|

| 硬碟 |

300|+--

------+-------+

6 rows in

set (0.03

sec)

mysql

>

SQL 行轉列,列轉行

行列轉換在做報表分析是還是經常會遇到的 行列轉換就是如下圖所示兩種展示形式互相轉換 只是做測試,建表比較隨意 create table student name varchar 20 subject int 10 score int 10 insert into student name,subje...

python 列轉行 SQL 行轉列,列轉行

sql 行轉列,列轉行 行列轉換在做報表分析時還是經常會遇到的,今天就說一下如何實現行列轉換吧。行列轉換就是如下圖所示兩種展示形式的互相轉換 行轉列假如我們有下表 select from student pivot sum score for subject in 語文,數學,英語 通過上面 sql...

sql 行轉列,列轉行整合

原始資料及結構如下 when 語文 then t.score else 0 end 語文,sum case t.subject when 數學 then t.score else 0 end 數學 sum case t.subject when 英語 then t.score else 0 end ...