SQL数据补全问题

一、造数据

DROP TABLE IF EXISTS sc;
CREATE TABLE sc (
	stu_no 	  VARCHAR(4) COMMENT '学号',
	class_no  VARCHAR(4) COMMENT '课程号',
	grade     INT(2)     COMMENT '成绩' 
);

DROP TABLE IF EXISTS class;
CREATE TABLE class (
	class_no   VARCHAR(4) COMMENT '课程号',
	class_name VARCHAR(8) COMMENT '课程名称'
);


INSERT INTO sc VALUES 
('0001','C001',89),
('0001','C002',85),
('0001','C003',99),
('0002','C001',78),
('0002','C002',83),
('0002','C003',86),
('0002','C004',77),
('0003','C001',88),
('0003','C003',68),
('0003','C004',55);

INSERT INTO class VALUES 
('C001','语文'),
('C002','数学'),
('C003','英语'),
('C004','科学');

二、查看数据结构

SELECT * FROM sc;
SELECT * FROM class;

在这里插入图片描述
在这里插入图片描述

三、需求 (查询出每个学生每一们课程的分数,如果该学生在数据库中没有那门课的分数,则那门课分数置为0)

  • 1.使用 cross join 对两张表做笛卡尔积。

    SELECT * 
    FROM sc
    CROSS JOIN class
    
    +--------+----------+-------+----------+------------+
    | stu_no | class_no | grade | class_no | class_name |
    +--------+----------+-------+----------+------------+
    | 0001   | C001     |    89 | C001     | 语文       |
    | 0001   | C001     |    89 | C002     | 数学       |
    | 0001   | C001     |    89 | C003     | 英语       |
    | 0001   | C001     |    89 | C004     | 科学       |
    | 0001   | C002     |    85 | C001     | 语文       |
    | 0001   | C002     |    85 | C002     | 数学       |
    | 0001   | C002     |    85 | C003     | 英语       |
    | 0001   | C002     |    85 | C004     | 科学       |
    | 0001   | C003     |    99 | C001     | 语文       |
    | 0001   | C003     |    99 | C002     | 数学       |
    | 0001   | C003     |    99 | C003     | 英语       |
    | 0001   | C003     |    99 | C004     | 科学       |
    | 0002   | C001     |    78 | C001     | 语文       |
    | 0002   | C001     |    78 | C002     | 数学       |
    | 0002   | C001     |    78 | C003     | 英语       |
    | 0002   | C001     |    78 | C004     | 科学       |
    | 0002   | C002     |    83 | C001     | 语文       |
    | 0002   | C002     |    83 | C002     | 数学       |
    | 0002   | C002     |    83 | C003     | 英语       |
    | 0002   | C002     |    83 | C004     | 科学       |
    | 0002   | C003     |    86 | C001     | 语文       |
    | 0002   | C003     |    86 | C002     | 数学       |
    | 0002   | C003     |    86 | C003     | 英语       |
    | 0002   | C003     |    86 | C004     | 科学       |
    | 0002   | C004     |    77 | C001     | 语文       |
    | 0002   | C004     |    77 | C002     | 数学       |
    | 0002   | C004     |    77 | C003     | 英语       |
    | 0002   | C004     |    77 | C004     | 科学       |
    | 0003   | C001     |    88 | C001     | 语文       |
    | 0003   | C001     |    88 | C002     | 数学       |
    | 0003   | C001     |    88 | C003     | 英语       |
    | 0003   | C001     |    88 | C004     | 科学       |
    | 0003   | C003     |    68 | C001     | 语文       |
    | 0003   | C003     |    68 | C002     | 数学       |
    | 0003   | C003     |    68 | C003     | 英语       |
    | 0003   | C003     |    68 | C004     | 科学       |
    | 0003   | C004     |    55 | C001     | 语文       |
    | 0003   | C004     |    55 | C002     | 数学       |
    | 0003   | C004     |    55 | C003     | 英语       |
    | 0003   | C004     |    55 | C004     | 科学       |
    +--------+----------+-------+----------+------------+
    
    
  • 2. 将上表中两个class_no 不相等的数据行,grade 置为0

    SELECT 
    	stu_no,
    	t1.class_no,
    	t2.class_no,
    	CASE 
    		WHEN t1.class_no=t2.class_no THEN grade 
    	ELSE 0 END AS grade,
    	class_name 
    FROM sc AS t1 
    CROSS JOIN class AS t2
    
    		+--------+----------+----------+-------+------------+
    | stu_no | class_no | class_no | grade | class_name |
    +--------+----------+----------+-------+------------+
    | 0001   | C001     | C001     |    89 | 语文       |
    | 0001   | C001     | C002     |     0 | 数学       |
    | 0001   | C001     | C003     |     0 | 英语       |
    | 0001   | C001     | C004     |     0 | 科学       |
    | 0001   | C002     | C001     |     0 | 语文       |
    | 0001   | C002     | C002     |    85 | 数学       |
    | 0001   | C002     | C003     |     0 | 英语       |
    | 0001   | C002     | C004     |     0 | 科学       |
    | 0001   | C003     | C001     |     0 | 语文       |
    | 0001   | C003     | C002     |     0 | 数学       |
    | 0001   | C003     | C003     |    99 | 英语       |
    | 0001   | C003     | C004     |     0 | 科学       |
    | 0002   | C001     | C001     |    78 | 语文       |
    | 0002   | C001     | C002     |     0 | 数学       |
    | 0002   | C001     | C003     |     0 | 英语       |
    | 0002   | C001     | C004     |     0 | 科学       |
    | 0002   | C002     | C001     |     0 | 语文       |
    | 0002   | C002     | C002     |    83 | 数学       |
    | 0002   | C002     | C003     |     0 | 英语       |
    | 0002   | C002     | C004     |     0 | 科学       |
    | 0002   | C003     | C001     |     0 | 语文       |
    | 0002   | C003     | C002     |     0 | 数学       |
    | 0002   | C003     | C003     |    86 | 英语       |
    | 0002   | C003     | C004     |     0 | 科学       |
    | 0002   | C004     | C001     |     0 | 语文       |
    | 0002   | C004     | C002     |     0 | 数学       |
    | 0002   | C004     | C003     |     0 | 英语       |
    | 0002   | C004     | C004     |    77 | 科学       |
    | 0003   | C001     | C001     |    88 | 语文       |
    | 0003   | C001     | C002     |     0 | 数学       |
    | 0003   | C001     | C003     |     0 | 英语       |
    | 0003   | C001     | C004     |     0 | 科学       |
    | 0003   | C003     | C001     |     0 | 语文       |
    | 0003   | C003     | C002     |     0 | 数学       |
    | 0003   | C003     | C003     |    68 | 英语       |
    | 0003   | C003     | C004     |     0 | 科学       |
    | 0003   | C004     | C001     |     0 | 语文       |
    | 0003   | C004     | C002     |     0 | 数学       |
    | 0003   | C004     | C003     |     0 | 英语       |
    | 0003   | C004     | C004     |    55 | 科学       |
    +--------+----------+----------+-------+------------+
    		
    
  • 3.观察上一个步骤中的数据不难发现,我们已经将每个学生缺失的课程分数用0补全,但是原本就正常的数据又重复了一些课程为0的数据,所以需要去重,去重无非就是用group by 或者 distinct ,但是distinct 不可控制,所以我们这里选用 group by 来去重得出我们想要的数据。

    SELECT 
    	stu_no,
    	t2.class_no,
    	SUM(CASE 
    		WHEN t1.class_no=t2.class_no THEN grade 
    		ELSE 0 
    		END
    		) AS grade,
    	class_name 
    FROM sc AS t1 
    CROSS JOIN class AS t2
    GROUP BY stu_no,t2.class_no,class_name;
    

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_42359956/article/details/109258786