學校裏面記錄成績,每一個人的選課不同,並且之後會添加課程,因此不須要把全部課程看成列。數據庫grade裏面數據以下圖,假定每一個人姓名都不同,做爲主鍵。本文以MySQL爲基礎,其餘數據庫會有些許語法不一樣。 html
下面介紹三種方法: 編碼
方法一: spa
SELECTDISTINCT a.name, (SELECTscoreFROMgrade bWHEREa.name=b.nameANDb.course='語文')AS'語文', (SELECTscoreFROMgrade bWHEREa.name=b.nameANDb.course='數學')AS'數學', (SELECTscoreFROMgrade bWHEREa.name=b.nameANDb.course='英語')AS'英語' FROMgrade a
方法二: 調試
SELECTname, SUM(CASE courseWHEN '語文'THENscoreEND)AS'語文', SUM(CASE courseWHEN '數學'THENscoreEND)AS'數學', SUM(CASE courseWHEN '英語'THENscoreEND)AS'英語' FROMgradeGROUPBYname
方法三: code
DELIMITER && CREATE PROCEDURE sp_count() BEGIN #課程名稱 DECLARE course_n VARCHAR(20); #全部課程數量 DECLARE count INT; #計數器 DECLARE i INT DEFAULT 0; #拼接SQL字符串 SET @s = 'SELECT name'; SET count = (SELECT COUNT(distinct course) FROM grade); WHILE i < count DO SET 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; END WHILE; SET @s = CONCAT(@s, ' FROM grade GROUP BY name'); #用於調試 #SELECT @s; PREPARE stmt FROM @s; EXECUTE stmt; END && call sp_count();
方法分析: htm
第一種方法使用了錶鏈接。
第二種使用了分組,對每一個分組分別處理。
第三種使用了存儲過程,實際上是第二種方法的動態化,先計算出全部課程的數量,而後對每一個分組進行課程查詢。
很明顯前兩種方法屬於硬編碼,增長課程後就須要修改SQL。而第三種則沒有這種問題。 blog
Note: 字符串
MySQL中不能在一個存儲過程當中刪除另外一個存儲過程,只能調用另外一個存儲過程
原本想在方法三裏面寫上:DROP PROCEDURE IF EXISTS sp_count();這是錯誤的。調試的時候若是寫錯了,只能手動刪除了,也沒找到好方法。
參考資料:
2013-8-8更新:
方法二還可使用IF語句。
以下所示:
SELECT name, SUM(IF (course = '語文' , score , null ) ) as '語文', SUM(IF (course = '數學' , score , null ) ) as '數學', SUM(IF (course = '英語' , score , null ) ) as '英語 ' FROM grade GROUP BY name