sql行轉列、列轉行的方法

  wKioL1j2vuCiSTLcAAAsXjQIOLM136.jpg-wh_50

如題:有一張表EMP,裏面有兩個字段:name,chengji  有三條記錄,分別表示語文(name) 70分,數學(name) 80分,英語(name) 58分,請用一條sql查詢出這三條記錄並以條件顯示出來,大於等於80表示優秀,大於等於60表示及格,小於60分表示不及格!要求顯示格式如上!sql

首先咱們建立表,添加如題數據!數據庫

CREATE TABLE emp(NAME VARCHAR(20),chengji INT);ide

INSERT INTO emp VALUES('語文',70),('數學',80),('英語',58);
函數

wKiom1j2wR6zupnhAABAFoIqvLA706.png-wh_50

根據題目要求,咱們須要將這三行的結果作判斷,而後以列的形式顯示,這其中有一個行轉列的操做。spa


第一種sql寫法:3d


SELECT MAX(CASE WHEN  NAME='語文' THEN (CASE WHEN chengji>=80  THEN '優秀' WHEN   chengji<80 AND chengji>=60 THEN '及格' ELSE  '不及格' END)  ELSE '' END) '語文'  ,blog

MAX(CASE WHEN  NAME='數學' THEN (CASE WHEN chengji>=80  THEN '優秀' WHEN   chengji<80 AND chengji>=60 THEN '及格' ELSE  '不及格' END)  ELSE '' END)  '數學',排序

MAX(CASE WHEN  NAME='英語' THEN (CASE WHEN chengji>=80  THEN '優秀' WHEN   chengji<80 AND chengji>=60 THEN '及格' ELSE  '不及格' END) ELSE '' END ) '英語' FROM  emp圖片

執行結果以下:字符串

wKiom1j2wx_ADv7ZAACGQcDPiHo897.png

  備註:上述sql中使用了max(case)這種用法,max這裏的主要做用是爲了在3次判斷中,取到不爲空字符串''的標題,語文,數學,英語!


 第二種寫法採用group_concat函數也是能夠拼接出如圖全部要的結果寫法以下:


SELECT GROUP_CONCAT(NAME SEPARATOR '|')  FROM   emp  UNION ALL   SELECT   

GROUP_CONCAT(CASE WHEN chengji>=80  THEN '優秀' WHEN   chengji<80 AND chengji>=60 THEN '及格' ELSE  '不及格' END   SEPARATOR '|' ) FROM  emp

執行結果以下:

wKioL1j2xPbxefwzAAB2E7FVth4984.png

這樣看,這個結果也仍是能夠接受, 這裏採用了group_concat函數,將列的類容鏈接起來,做爲行!不過這樣的結果有點生硬的感受!


補充一點:這裏的sql寫法咱們能夠看出,若是想要經過第一種寫法。咱們前面必需要知道列的內容如語文,數學,英語,可是第二種咱們卻不用知道! 這裏咱們想到了一種方法,經過存儲過程,將想要的第一種方法的sql拼出來,而後執行這樣的話,後面若是咱們的表再添加列,或者減小列,也不會報錯!

寫法以下:

DELIMITER $$


USE `yhtest`$$


DROP PROCEDURE IF EXISTS `yhtest`$$


CREATE DEFINER=`root`@`%` PROCEDURE `yhtest`()

BEGIN

SET @sql = NULL;

SELECT

  GROUP_CONCAT(DISTINCT

    CONCAT(

       'MAX(CASE WHEN  NAME=','\'',emp.name,'\'','THEN (CASE WHEN chengji>=80  THEN ', '\'' ,'優秀','\'' ,' WHEN  

        chengji<80 AND chengji>=60 THEN ', '\'' ,'及格' ,'\'' ,' ELSE ', '\'' ,'不及格' ,'\'' ,' END)  ELSE ', '\'','\'',' END) ','\'',emp.name,'\'' 

    )

  )

INTO @sql

FROM emp ;

SET @sql = CONCAT('select  ',@sql, ' from  emp');

PREPARE stmt1 FROM @sql;

EXECUTE stmt1;

DEALLOCATE PREPARE stmt1;

  END$$


DELIMITER ;

調用一下: call yhtest();

wKiom1j20nKh9jtuAAA_Q-vr4wI845.png-wh_50

插入幾條數據!咱們假設提早不知道有多少個科目!

INSERT INTO emp VALUES('物理',72),('體育',84);

wKiom1j211WxucwvAABBljvNV5g784.png

這裏有個問題!因爲咱們在存儲過程當中使用了group_concat函數,這個拼接函數最大拼接長度爲1024(默認) 超過固定長度,截斷處理! 由數據庫參數group_concat_max_len 控制!咱們能夠根據須要認爲調整!


group_concat  調整拼接符號 group_concat(name  separator  '_')

group_concat  排序:group_concat(name order by name  separator  '_')

相關文章
相關標籤/搜索