MySQL存储过程的动态行转列

表1

DROP TABLE IF EXISTS `tuser`;
CREATE TABLE `tuser`  (
  `loginid` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
  `watchtime` double NULL DEFAULT NULL,
  `courseid` int(0) NULL DEFAULT NULL
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;

INSERT INTO `tuser` VALUES ('L1', 0.56, 2);
INSERT INTO `tuser` VALUES ('L1', 0.66, 2);
INSERT INTO `tuser` VALUES ('L1', 0.66, 2);
INSERT INTO `tuser` VALUES ('L2', 0.57, 2);
INSERT INTO `tuser` VALUES ('L2', 0.57, 2);
INSERT INTO `tuser` VALUES ('L2', 0.57, 1);

在这里插入图片描述

表2

DROP TABLE IF EXISTS `t1`;
CREATE TABLE `t1`  (
  `id` int(0) NOT NULL AUTO_INCREMENT,
  `course` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;

INSERT INTO `t1` VALUES (1, '科目1');
INSERT INTO `t1` VALUES (2, '科目2');
INSERT INTO `t1` VALUES (3, '科目3');

在这里插入图片描述

存储过程行转列

DROP PROCEDURE IF EXISTS t_proc;  
CREATE PROCEDURE t_proc() 
BEGIN
    DECLARE esql VARCHAR(4000) ;
    DECLARE tid INT;
    DECLARE tname VARCHAR(50);
    DECLARE flag INT DEFAULT 0;
 
    ## 定义一个游标来记录sql查询的结果
    DECLARE t_list CURSOR FOR select id,course from t1 ORDER BY id; 
    ## 为下面while循环建立一个退出标志,当游标遍历完后将flag的值设置为1
    DECLARE continue handler for not found SET flag = 1;
 
    SET @esql = 'SELECT d.loginid  AS \'loginid\' ' ;
    
    ## 打开游标
    OPEN t_list;
    ## 将游标中的值赋给定义好的变量,实现for循环的要点
    FETCH t_list INTO  tid, tname;
    WHILE flag <> 1 DO
        ## SELECT  tid, tname;
        SET @tsql = ', ROUND(sum(if (d.courseid = ' + tid+ ', d.watchtime, 0 )),2) AS \'' + tname+ '\''  ;
    ## SELECT @tsql;
    SET @esql = concat(@esql, ', ROUND(sum(if (d.courseid = ' , tid , ', d.watchtime, 0 )),2) AS \'' , tname, '\'' ) ;
    FETCH t_list INTO  tid, tname;
 
    END WHILE ;
    ## 关闭游标
    CLOSE t_list ;
    SET @esql = CONCAT(@esql ,' FROM  tuser  d  GROUP BY d.loginid;') ;
 
    PREPARE stmt FROM @esql;-- 预编译一条sql语句,并命名为stmt
    EXECUTE stmt;-- 执行预编译sql
 
    ## 拼接完成后可以调用 select @s 语句,查看最终拼接的sql语句是否正确
    ##select @esql;
END

调用结果

调用存储过程:call t_proc();

在这里插入图片描述

查看存储过程执行的sql:select @esql;
在这里插入图片描述

普通行转列

SELECT loginid,
  sum(
  CASE
    WHEN courseid='1'
    THEN watchtime
    ELSE 0
  END) AS "科目一",
  sum(
  CASE
    WHEN courseid='2'
    THEN watchtime
    ELSE 0
  END) AS "科目二",
  sum(
  CASE
    WHEN courseid='3'
    THEN watchtime
    ELSE 0
  END) AS "科目三"
FROM tuser
GROUP BY loginid
  • 4
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

xcLeigh

万水千山总是情,打赏两块行不行

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值