数据库查询-数据集合的行转查询的列;一个表的所有数据作为查询的列

以查询每个学生没门课程的成绩为例。

第一步:创建数据库。

-- 创建数据库,格式为 utf-8
CREATE DATABASE test CHARACTER SET utf8 COLLATE utf8_general_ci;

-- 切换到创建的数据库下
use test;
-- 学生表
CREATE TABLE student (     
    id INT PRIMARY KEY AUTO_INCREMENT,     
    sname VARCHAR(30) NOT NULL , 
    sex VARCHAR(10) DEFAULT 'male'
);
-- 课程表
CREATE TABLE course(
    id INT PRIMARY KEY AUTO_INCREMENT,
    cname VARCHAR(30) NOT NULL
);
-- 成绩表
CREATE TABLE results(
    id INT PRIMARY KEY AUTO_INCREMENT,
    sid INT NOT NULL,
    cid INT NOT NULL,
    result INT NOT NULL,
    CONSTRAINT STUDENTID FOREIGN KEY(sid) REFERENCES student(id),
    CONSTRAINT COURSEID FOREIGN KEY(cid) REFERENCES course(id)
);

 

第二步:插入测试数据,使用存储过程。

 

CREATE DEFINER=`root`@`%` PROCEDURE `InsertResult`()
BEGIN
    -- 插入5000条学生的信息
    SET @num = 1;
    WHILE @num <= 5000 DO
    
        SET @studentname = '学生';
        
        INSERT INTO student (sname) VALUES (CONCAT(@studentname,@num)),
        (CONCAT(@studentname,@num + 1)),
        (CONCAT(@studentname,@num + 2)),
        (CONCAT(@studentname,@num + 3)),
        (CONCAT(@studentname,@num + 4)),
        (CONCAT(@studentname,@num + 5)),
        (CONCAT(@studentname,@num + 6)),
        (CONCAT(@studentname,@num + 7)),
        (CONCAT(@studentname,@num + 8)),
        (CONCAT(@studentname,@num + 9)),
        (CONCAT(@studentname,@num + 10)),
        (CONCAT(@studentname,@num + 11)),
        (CONCAT(@studentname,@num + 12)),
        (CONCAT(@studentname,@num + 13)),
        (CONCAT(@studentname,@num + 14)),
        (CONCAT(@studentname,@num + 15)),
        (CONCAT(@studentname,@num + 16)),
        (CONCAT(@studentname,@num + 17)),
        (CONCAT(@studentname,@num + 18)),
        (CONCAT(@studentname,@num + 19)),
        (CONCAT(@studentname,@num + 20));
        
        SET @num = @num + 20;
    END WHILE;
    
    -- 插入课程信息
    INSERT INTO course (cname) VALUES ('课程1'),('课程2'),('课程3'),('课程4'),('课程5');
    
    -- 为每个学生分别插入每门课程的成绩
    SET @num = 1;
    WHILE @num <= 5000 DO
        
        INSERT INTO results (sid,cid,result) VALUES (@num,1,91),(@num,2,92),(@num,3,93),(@num,4,94),(@num,5,95),
        (@num + 1,1,91),(@num + 1,2,92),(@num + 1,3,93),(@num + 1,4,94),(@num + 1,5,95),
        (@num + 2,1,91),(@num + 2,2,92),(@num + 2,3,93),(@num + 2,4,94),(@num + 2,5,95),
        (@num + 3,1,91),(@num + 3,2,92),(@num + 3,3,93),(@num + 3,4,94),(@num + 3,5,95),
        (@num + 4,1,91),(@num + 4,2,92),(@num + 4,3,93),(@num + 4,4,94),(@num + 4,5,95),
        (@num + 5,1,91),(@num + 5,2,92),(@num + 5,3,93),(@num + 5,4,94),(@num + 5,5,95),
        (@num + 6,1,91),(@num + 6,2,92),(@num + 6,3,93),(@num + 6,4,94),(@num + 6,5,95),
        (@num + 7,1,91),(@num + 7,2,92),(@num + 7,3,93),(@num + 7,4,94),(@num + 7,5,95),
        (@num + 8,1,91),(@num + 8,2,92),(@num + 8,3,93),(@num + 8,4,94),(@num + 8,5,95),
        (@num + 9,1,91),(@num + 9,2,92),(@num + 9,3,93),(@num + 9,4,94),(@num + 9,5,95);
        
        
        SET @num = @num + 10;
    END WHILE;
END

表数据:

学生表:

课程表:

成绩表:

第三步:编写查询的存储过程,将课程表中的课程转换成查询的列。

CREATE DEFINER=`root`@`%` PROCEDURE `FindResult`(IN `pageOffSet` varchar(256),IN `pageRows` varchar(256))
BEGIN
    -- 更改GROUP_CONCAT的长度
    SET GLOBAL group_concat_max_len=102400; 
    SET SESSION group_concat_max_len=102400; 
    
    -- 执行的sql
    SET @sql = NULL;
    
    -- 数据集合的行转查询的列
    SELECT
        GROUP_CONCAT(DISTINCT
            CONCAT(
                '(SELECT R.result FROM results AS R,course AS C,student AS S WHERE
                R.sid = S.id AND R.cid = C.id AND S.id = ST.id AND C.id = ',c.id,') AS \'',c.cname,'\''
            )
        ) INTO @sql
    FROM course c;

    -- 查询语句
    SET @sql = CONCAT('SELECT ST.sname ,', @sql, 
                        ' FROM student AS ST LIMIT ',pageOffSet,',',pageRows);
                                                    
    -- 定义
    PREPARE result FROM @sql;
    -- 执行预处理
    EXECUTE result;
    -- 删除
    DEALLOCATE PREPARE result;

END

 

结果:

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值