mysql行轉列

//---------------------------------------------------------題1 start-------------------------------------------------------------sql

數據表:微信

CREATE TABLE `t_shcool` (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '自增主鍵',
  `userName` varchar(50) DEFAULT NULL COMMENT '姓名',
  `course` varchar(50) DEFAULT NULL COMMENT '科目',
  `score` int(20) DEFAULT NULL COMMENT '成績',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8;

 

insert  into `t_shcool`
(`id`,`userName`,`course`,`score`) 
values 
(1,'張三','語文',66),
(2,'張三','數學',77),
(3,'張三','英文',88),
(4,'李四','語文',99),
(5,'李四','數學',100),
(6,'李四','英文',55),
(7,'王五','語文',44),
(8,'王五','數學',33),
(9,'馬六','英文',22),
(10,'馬六','語文',11);

  

如:
fetch

 

查詢sql:spa

SELECT 
userName AS '姓名',
SUM(CASE  WHEN course='語文' THEN score ELSE 0 END) AS '語文',
SUM(CASE  WHEN course='數學' THEN score ELSE 0 END) AS '數學',
SUM(CASE  WHEN course='英文' THEN score ELSE 0 END) AS '英文'
FROM t_shcool GROUP BY userName

 

上面只能查詢當前表,若是表中新增「物理」科目,則sql就無效了code

 

//---------------------------------------------------------題1 end-------------------------------------------------------------內存

 

//---------------------------------------------------------題2 start-------------------------------------------------------------資源

CREATE TABLE `TabName` (
  `Id` int(11) NOT NULL AUTO_INCREMENT,
  `Name` varchar(20) DEFAULT NULL,
  `Date` date DEFAULT NULL,
  `Scount` int(11) DEFAULT NULL,
  PRIMARY KEY (`Id`)
) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=utf8;

 

INSERT INTO `TabName` VALUES ('1', '小說', '2013-09-01', '10000');
INSERT INTO `TabName` VALUES ('2', '微信', '2013-09-01', '20000');
INSERT INTO `TabName` VALUES ('3', '小說', '2013-09-02', '30000');
INSERT INTO `TabName` VALUES ('4', '微信', '2013-09-02', '35000');
INSERT INTO `TabName` VALUES ('5', '小說', '2013-09-03', '31000');
INSERT INTO `TabName` VALUES ('6', '微信', '2013-09-03', '36000');
INSERT INTO `TabName` VALUES ('7', '小說', '2013-09-04', '35000');
INSERT INTO `TabName` VALUES ('8', '微信', '2013-09-04', '38000');

 

-- ------------------------
-- 查看數據
-- ------------------------
SELECT  * from TabName ;

  

 

-- ------------------------
-- 列轉行統計數據
-- ------------------------
SELECT Date ,
MAX(CASE NAME WHEN '小說' THEN Scount ELSE 0 END ) 小說,
MAX(CASE NAME WHEN '微信' THEN Scount ELSE 0 END ) 微信 
FROM TabName  
GROUP BY Date

 

 

-- ------------------------
-- 行轉列統計數據
-- ------------------------

 

 

select
    Date, group_concat(NAME,'總量:',Scount) as b_str from   TabName 
 group by Date

 



 

select Date,NAME, group_concat(NAME,'總量:',Scount) as b_str from   TabName 
 group by Date ,NAME

 

 

//---------------------------------------------------------題2 end-------------------------------------------------------------數學

 

//---------------------------------------------------------題3 start-------------------------------------------------------------table

CREATE TABLE `user` (
  `name` varchar(50) DEFAULT NULL,
  `subject` varchar(50) DEFAULT NULL,
  `score` int(11) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

 

insert into user values
('zhangsan' , 'chinese' , 10),
('zhangsan' , 'math' , 20),
('zhangsan' , 'english' , 30),
('lily' , 'chinese' , 40),
('lily' , 'math' , 50),
('lily' , 'english' , 60),
('mini' , 'chinese' , 70),
('mini' , 'math' , 80),
('mini' , 'english' , 90);

 

 

case when 實現行轉列class

SELECT NAME,
SUM( CASE SUBJECT WHEN 'chinese' THEN score ELSE 0 END)  AS 'chinese',
SUM( CASE SUBJECT WHEN 'math' THEN score ELSE 0 END) AS 'math',
SUM( CASE SUBJECT WHEN 'english' THEN score ELSE 0 END) AS 'english'
FROM USER
GROUP BY NAME;

  存儲過程實現行轉列

create  procedure line_to_col()
begin
  declare i int;
  declare _chinese int;
  declare _math int;
  declare _english int;
  declare _name varchar(10);
  declare test_cursor CURSOR for select name from user;
  select count(*) into i from user;
  CREATE TEMPORARY TABLE tmp_tab(
    name varchar(10),
    chinese_score int,
    math_socre int,
    english_score int); 
  if i> 0 then
    open test_cursor;
    repeat fetch test_cursor into _name;
      select score into _chinese from user where subject = 'chinese' and name =_name;
      select score into _math from user where subject = 'math'  and name =_name;
      select score into _english from user where subject = 'english'  and name =_name;
      insert into tmp_tab values(_name,_chinese,_math,_english);
      set i=i-1;
    until i=0 end repeat;
    close test_cursor;
  end if;
  select DISTINCT * from tmp_tab;
  drop table tmp_tab;
end

 

在寫存儲過程的時候遇到了兩個問題,分別是關於遊標和臨時表。

由於user表中有重複的name,在設置遊標時,我想直接過濾掉重複的用戶,因此將遊標設置成 declare test_cursor CURSOR for select  DISTINCT name from user;這樣設置遊標以後,執行存儲過程,報錯提示沒有獲取任何數據。小小同志跟我解釋說, 遊標是遍歷用的,怎麼能distinct呢 ,只能對取數作distinct。

爲了拼接輸出內容,我建了一個臨時表,第一次調用line_to_col的時候能夠正常執行,第二次調用時就報錯提示tmp_tab已存在。因此在存儲過程當中建立臨時表,執行完後,須要及時把臨時表刪除掉,避免重複調用時出錯。另外,小小跟我強調,臨時表是放在內存裏的,會耗資源,因此在用完以後須要及時刪除掉。

 

//---------------------------------------------------------題3 end-------------------------------------------------------------

相關文章
相關標籤/搜索