情景簡介
學校裡面記錄成績,每個人的選課不一樣,而且以後會新增課程,所以不需要把所有課程當作列。資料庫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
>
下面介紹三種方法:
方法一:
selectdistinct
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
方法二:
selectname,
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 ...