SELECT s.s_id,s.s_name,c.c_name,sc.s_score
FROM student s
LEFT JOIN score sc on sc.s_id = s.s_id
LEFT JOIN course c on c.c_id = sc.c_id
好的,现在呢我们要把课程名称呢变成横行,该怎么做呢?
SELECT p.s_id,
p.s_name,
MAX(IF(p.c_name = '数学', p.s_score, NULL)) AS 数学,
MAX(IF(p.c_name = '语文', p.s_score, NULL)) AS 语文,
MAX(IF(p.c_name = '英语', p.s_score, NULL)) AS 英语
FROM (
SELECT s.s_id,s.s_name,c.c_name,sc.s_score
FROM student s
LEFT JOIN score sc on sc.s_id=s.s_id
LEFT JOIN course c on c.c_id = sc.c_id )p
GROUP BY p.s_id;
接下来请看动态SQL
我们的动态sql是拼接实现的,所以要先看一下
SELECT CONCAT( 'MAX(IF(p.c_name = ''', s_name, ''', p.s_score, NULL)) AS ', s_name ) FROM student S;
是的,结果就是上面要的MAX函数
接下来,拼接sql实现需求
--1.定义一个sql变量
SET @sql = NULL;
--2.查询所有要列转行的变量
SELECT
GROUP_CONCAT(DISTINCT
CONCAT(
'MAX(IF(p.c_name = ''',
c_name,
''', p.s_score, NULL)) AS ',
c_name
)
) INTO @sql
FROM course;
--3.拼接sql
SET @sql = CONCAT('SELECT p.s_id, p.s_name, ', @sql ,'
FROM (SELECT s.s_id,s.s_name,c.c_name,sc.s_score
FROM student s
LEFT JOIN score sc on sc.s_id=s.s_id
LEFT JOIN course c on c.c_id = sc.c_id)p
GROUP BY p.s_id');
-- 预处理语句
PREPARE stmt FROM @sql;
-- 执行
EXECUTE stmt;
-- 销毁
DEALLOCATE PREPARE stmt;
好的 那么我们来封装成存储过程
-- 1、创建无参存储过程
delimiter $$
CREATE PROCEDURE getStudentRow()
BEGIN
------把要执行的sql放在这里就可以了
SET @sql = NULL;
SELECT
GROUP_CONCAT(DISTINCT CONCAT('MAX(IF(p.c_name = ''',c_name,''', p.s_score, NULL)) AS ',c_name))
INTO @sql FROM course;
SET @sql = CONCAT('SELECT p.s_id, p.s_name, ', @sql ,'
FROM (SELECT s.s_id,s.s_name,c.c_name,sc.s_score
FROM student s
LEFT JOIN score sc on sc.s_id=s.s_id
LEFT JOIN course c on c.c_id = sc.c_id)p
GROUP BY p.s_id');
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
------把要执行的sql放在这里就可以了
END$$;
delimiter;
-- 查询存储过程
SHOW PROCEDURE STATUS;
-- 调用
CALL getStudentRow();
-- ----------------------------
-- Table structure for student
-- ----------------------------
DROP TABLE IF EXISTS `student`;
CREATE TABLE `student` (
`s_id` varchar(20) NOT NULL DEFAULT '',
`s_name` varchar(20) NOT NULL DEFAULT '',
`s_birth` varchar(20) NOT NULL DEFAULT '',
`s_sex` varchar(10) NOT NULL DEFAULT '',
PRIMARY KEY (`s_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- ----------------------------
-- Records of student
-- ----------------------------
INSERT INTO `student` VALUES ('01', '赵雷', '1990-01-01', '男');
INSERT INTO `student` VALUES ('02', '钱电', '1990-12-21', '男');
INSERT INTO `student` VALUES ('03', '孙风', '1990-05-20', '男');
INSERT INTO `student` VALUES ('04', '李云', '1990-08-06', '男');
INSERT INTO `student` VALUES ('05', '周梅', '1991-12-01', '女');
INSERT INTO `student` VALUES ('06', '吴兰', '1992-03-01', '女');
INSERT INTO `student` VALUES ('07', '郑竹', '1989-07-01', '女');
INSERT INTO `student` VALUES ('08', '王菊', '1990-01-20', '女');
-- ----------------------------
-- Table structure for course
-- ----------------------------
DROP TABLE IF EXISTS `course`;
CREATE TABLE `course` (
`c_id` varchar(20) NOT NULL DEFAULT '',
`c_name` varchar(20) NOT NULL DEFAULT '',
`t_id` varchar(20) NOT NULL,
PRIMARY KEY (`c_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- ----------------------------
-- Records of course
-- ----------------------------
INSERT INTO `course` VALUES ('01', '语文', '02');
INSERT INTO `course` VALUES ('02', '数学', '01');
INSERT INTO `course` VALUES ('03', '英语', '03');
-- ----------------------------
-- Table structure for score
-- ----------------------------
DROP TABLE IF EXISTS `score`;
CREATE TABLE `score` (
`s_id` varchar(20) NOT NULL DEFAULT '',
`c_id` varchar(20) NOT NULL DEFAULT '',
`s_score` int(3) DEFAULT NULL,
PRIMARY KEY (`s_id`,`c_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- ----------------------------
-- Records of score
-- ----------------------------
INSERT INTO `score` VALUES ('01', '01', '80');
INSERT INTO `score` VALUES ('01', '02', '90');
INSERT INTO `score` VALUES ('01', '03', '99');
INSERT INTO `score` VALUES ('02', '01', '70');
INSERT INTO `score` VALUES ('02', '02', '60');
INSERT INTO `score` VALUES ('02', '03', '80');
INSERT INTO `score` VALUES ('03', '01', '80');
INSERT INTO `score` VALUES ('03', '02', '80');
INSERT INTO `score` VALUES ('03', '03', '80');
INSERT INTO `score` VALUES ('04', '01', '50');
INSERT INTO `score` VALUES ('04', '02', '30');
INSERT INTO `score` VALUES ('04', '03', '20');
INSERT INTO `score` VALUES ('05', '01', '76');
INSERT INTO `score` VALUES ('05', '02', '87');
INSERT INTO `score` VALUES ('06', '01', '31');
INSERT INTO `score` VALUES ('06', '03', '34');
INSERT INTO `score` VALUES ('07', '02', '89');
INSERT INTO `score` VALUES ('07', '03', '98');
这样每次直接调用就可以了,你学费了吗?