SQL面试50题

数据表关系图

在这里插入图片描述

数据表

CREATE TABLE `student` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) NOT NULL,
  `sex` enum('female','male') NOT NULL,
  `birth` date NOT NULL,
  `credit` float(5,2) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=25 DEFAULT CHARSET=utf8;

CREATE TABLE `teacher` (
  `id` int(11) NOT NULL,
  `name` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

CREATE TABLE `course` (
  `id` int(11) NOT NULL,
  `name` varchar(255) DEFAULT NULL,
  `tid` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

CREATE TABLE `score` (
  `sid` int(11) NOT NULL,
  `cid` int(11) NOT NULL,
  `score` float(5,2) DEFAULT NULL,
  PRIMARY KEY (`sid`,`cid`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

添加学生表数据

存储过程,添加 学生表student

DELETE FROM student;
ALTER TABLE student AUTO_INCREMENT = 1;


DROP TABLE IF EXISTS temp_stu;
CREATE TEMPORARY TABLE temp_stu(
    name VARCHAR(255)
);

INSERT INTO `temp_stu` (`name`) VALUES ('张三'),('李四'),('王五'),('赵六'),('牛金霞'),('闫景立'),('孙浩'),('周莉'),('吴鹏'),('郑洁'),('陈婷婷'),('刘洋'),('高敏'),('黄磊'),('林静'),('郭涛'),('何婉如'),('梁志远'),('罗芳芳'),('谢霆锋'),('唐嫣'),('韩雪'),('冯小刚'),('程思远');


DROP PROCEDURE IF EXISTS insert_student_records;

DELIMITER //

CREATE PROCEDURE insert_student_records()
BEGIN
    DECLARE done INT DEFAULT FALSE;
    DECLARE student_name VARCHAR(255);
    DECLARE student_sex ENUM('female', 'male');
    DECLARE random_year INT;
    DECLARE random_month INT;
    DECLARE random_day INT;
    DECLARE days_in_month INT;
		DECLARE credit FLOAT(5,2);
    
    -- 声明游标
    DECLARE nameset CURSOR FOR SELECT name FROM temp_stu;
    -- 声明继续处理程序
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
    
    OPEN nameset;
    
    read_loop: LOOP
        FETCH nameset INTO student_name;
        IF done THEN
            LEAVE read_loop;
        END IF;
        
	
        SET student_sex = IF(RAND() < 0.5, 'female', 'male');
        
        -- 随机选择一个年份(1994, 1995, 1997, 1998, 1999)
        SET random_year = FLOOR(1 + RAND() * 5) + 1993; 
				
				IF random_year = 1996 THEN
            SET random_year = CASE FLOOR(RAND() * 4) + 1994 WHEN 1996 THEN 1994 + FLOOR(RAND() * 4) ELSE random_year - 1 END; 
				END IF;
        
        SET random_month = FLOOR(1 + RAND() * 12);
        
        -- 计算该月的天数(考虑闰年)
        SET days_in_month = CASE
            WHEN (random_month = 2 AND (random_year % 4 = 0 AND (random_year % 100 != 0 OR random_year % 400 = 0))) THEN 29
            WHEN random_month IN (4, 6, 9, 11) THEN 30
            ELSE 31
        END;
        
        SET random_day = FLOOR(1 + RAND() * days_in_month);
        
        SET @birth_date = CONCAT(random_year, '-', LPAD(random_month, 2, '0'), '-', LPAD(random_day, 2, '0'));
				
				SET credit = CASE 
						WHEN RAND() < 0.1 THEN 50 - 30 * RAND() 
						WHEN RAND() < 0.7 THEN 50 + 30 * RAND()
						ELSE 80 + 20 * RAND()	
				END;
 
        
        -- 插入到student表
        INSERT INTO student(name, sex, birth, credit) VALUES(student_name, student_sex, @birth_date, ROUND(credit, 2));
        
    END LOOP;
    
    CLOSE nameset;

END //

DELIMITER ;

-- SHOW CREATE PROCEDURE insert_student_records;
CALL insert_student_records();

DROP PROCEDURE IF EXISTS insert_student_records;
SELECT * FROM student;

其他表

-- 清理环境
DELETE FROM course;
DELETE FROM teacher;
DELETE FROM score;
DROP PROCEDURE IF EXISTS insert_course_records;
DROP PROCEDURE IF EXISTS insert_teacher_records;
DROP PROCEDURE IF EXISTS insert_score_records;

DROP TABLE IF EXISTS temp_course;
CREATE TEMPORARY TABLE temp_course (
    value VARCHAR(255)
);

-- 插入数据到临时表
INSERT INTO temp_course (value) VALUES ('语文'), ('数学'), ('英语'), ('政治'), ('地理'), ('历史'), ('物理'), ('化学'), ('生物'), ('C++'), ('Python'), ('机器学习'), ('强化学习'), ('自然语言处理'), ('关联规则挖掘');


DROP TABLE IF EXISTS temp_teacher;
CREATE TEMPORARY TABLE temp_teacher (
    value VARCHAR(255)
);

-- 插入数据到临时表
INSERT INTO temp_teacher (value) VALUES ('李明'), ('王芳'), ('张伟'), ('赵敏'), ('刘洋'), ('陈静'), ('周杰'), ('孙磊'),('徐丽'), ('朱强'), ('邓敏'), ('韩雪');



DELIMITER //

CREATE PROCEDURE insert_course_records()
BEGIN
		DECLARE done INT DEFAULT FALSE;
		DECLARE course_id INT DEFAULT 1;
		DECLARE course_name VARCHAR(255);
		DECLARE course_num	INT DEFAULT 15;
		DECLARE teacher_num INT DEFAULT 12;
		
		
		-- 声明游标
    DECLARE courseset CURSOR FOR SELECT value FROM temp_course;
    -- 声明继续处理程序
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
		
		
		OPEN courseset;
    
    read_loop: LOOP
        FETCH courseset INTO course_name;
        IF done THEN
            LEAVE read_loop;
        END IF;
				
			SET @teacher_id = CEILING(teacher_num * RAND());
			
			INSERT INTO course(id, name, tid) VALUES(course_id, course_name, @teacher_id);
			
			SET course_id = course_id +1;
			
			END LOOP read_loop;
			
			CLOSE courseset;
	
	
END //


CREATE PROCEDURE insert_teacher_records()
BEGIN
		DECLARE done INT DEFAULT FALSE;
		DECLARE teacher_id INT DEFAULT 1;
		DECLARE teacher_name VARCHAR(255);
		
		DECLARE teacherset CURSOR FOR SELECT value FROM temp_teacher;
		DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
		
		OPEN teacherset;
    
    read_loop: LOOP
        FETCH teacherset INTO teacher_name;
        IF done THEN
            LEAVE read_loop;
        END IF;
				
				INSERT INTO teacher(id, name) VALUES(teacher_id, teacher_name);
				
				SET teacher_id = teacher_id + 1;
		
		END LOOP read_loop;
		
		CLOSE teacherset;
		
END //



CREATE PROCEDURE insert_score_records()
BEGIN
		DECLARE student_num INT DEFAULT 24;
		DECLARE course_num INT DEFAULT 15;
		
		DECLARE student_id INT DEFAULT 1;
		DECLARE course_id INT DEFAULT 1;
		DECLARE score FLOAT(5,2);
		
		
		WHILE student_id <= student_num DO
				SET @temp_course_num = FLOOR(course_num / 3	* RAND());
				SET @course_idx  = 1;
				WHILE @course_idx <= @temp_course_num DO
						SET course_id = CASE 
								WHEN RAND() < 0.4 THEN  @course_idx
								WHEN RAND() < 0.5 THEN  FLOOR(course_num / 3) + @course_idx
								ELSE FLOOR(course_num	/ 3 * 2) + @course_idx
						END ;
						SET score = CASE
								WHEN RAND() < 0.3 THEN ROUND(50 - 20 * RAND(), 2)
								WHEN RAND() < 0.8 THEN ROUND(50 + 30 * RAND(), 2)
								ELSE ROUND(80 + 20 * RAND(), 2)
						END ;
						INSERT INTO score(sid,cid, score) VALUES(student_id, course_id, score);
						SET @course_idx = @course_idx + 1; 
				END WHILE;
				SET student_id = student_id + 1;
		END WHILE;
END//


DELIMITER ;



CALL insert_course_records();
CALL insert_teacher_records();
CALL insert_score_records();

DROP PROCEDURE IF EXISTS insert_course_records;
DROP PROCEDURE IF EXISTS insert_teacher_records;
DROP PROCEDURE IF EXISTS insert_score_records;

SELECT * from course;
SELECT * from teacher;
SELECT * FROM score;

查询示例

  • 查询语文成绩比数学成绩高的学生
-- 第一题-查询课程编号为01的课程比02的课程成绩低的所有学生的学号(重要)

SELECT id, name, a.score '语文' , b.score '数学' FROM student 
	JOIN (SELECT sid, score FROM score WHERE cid = 1) a on id = a.sid
	JOIN (SELECT sid, score FROM score WHERE cid = 2) b on id = b.sid
	WHERE a.score < b.score;
			

-- 第二题-查询平均成绩大于60分的学生的学号和平均成绩

SELECT id, name, a.avg_score FROM student
 RIGHT JOIN( SELECT sid , ROUND(AVG(score), 2) avg_score FROM score
								GROUP BY sid
								HAVING avg_score > 60) a on student.id = a.sid;
								
								
-- 第三题-查询所有学生的学号、姓名、选课数、总成绩

SELECT id, name, IF (ISNULL(a.selected_course),0,a.selected_course) '选课数', IF(ISNULL(a.sum_score),0,a.sum_score) '总成绩' FROM student
		LEFT JOIN (SELECT sid, count(score)	selected_course, SUM(score) sum_score FROM score GROUP BY sid) a on student.id = a.sid;
										
										
-- 第四题-查询姓猴的老师的个数

SELECT COUNT(*) FROM teacher 
		WHERE `name` LIKE '朱%';
		
-- 第五题-查询没学过张三老师课的学生的学号和姓名(重要)

-- SELECT  tid, temp.`name` ,GROUP_CONCAT(course.name) FROM course JOIN (SELECT * FROM teacher) temp  ON course.tid = temp.id GROUP BY tid,temp.`name`;
-- 邓敏老师

SELECT id, `name` FROM student WHERE id NOT IN (
	SELECT sid FROM score WHERE cid IN (
		SELECT id FROM course WHERE tid = 
			(SELECT id from teacher WHERE `name` = '邓敏') 

	)
);

-- 学过邓敏课程的学生		
SELECT id, name, score.cid  FROM student	JOIN score ON id = score.sid
		WHERE  score.cid IN (SELECT id FROM course	WHERE tid = (SELECT id FROM teacher WHERE `name` = '邓敏' ));
	

SELECT id, name FROM student WHERE id NOT IN(
		-- 学过邓敏课程的学生		
		SELECT id  FROM student	JOIN score ON id = score.sid
				WHERE  score.cid IN (SELECT id FROM course	WHERE tid = (SELECT id FROM teacher WHERE `name` = '邓敏' ))
);


-- 文心一言优化
SELECT s.id, s.name FROM student s
	WHERE s.id NOT IN (
				SELECT sc.sid	FROM score sc
						JOIN course c ON sc.cid = c.id
						JOIN teacher t ON c.tid = t.id
					WHERE t.name = '邓敏'
);

-- 第六题-查询学过张三老师所教的所有课的同学的学号和姓名(重要)

-- 查询所教的课程数目大于1的老师
SELECT teacher.`name` , GROUP_CONCAT(course.`name`) FROM teacher 
		JOIN course on course.tid = teacher.id
		GROUP BY teacher.id, teacher.`name`
		HAVING COUNT(*) > 1;

-- 查询所选的课程数目大于1的学生
SELECT student.`name`, GROUP_CONCAT(course.`name`)  FROM student
		JOIN score ON score.sid = student.id
		JOIN course ON course.id = score.cid
		GROUP BY student.id, student.`name`
		HAVING COUNT(*) > 1;
		


-- 学过李明老师课程的学生		
SELECT student.`name`, GROUP_CONCAT(course.`name`) AS '科目', GROUP_CONCAT(score.score) '成绩' FROM student
		JOIN score ON student.id = score.sid
		JOIN course ON course.id = score.cid
		JOIN (SELECT * FROM teacher WHERE teacher.`name` = '李明') t ON t.id = course.tid
		GROUP BY student.id, student.`name`;
		
		

-- 所有科目:通过数目进行判断
SELECT s.id, s.name FROM student s
		JOIN score sc ON s.id = sc.sid
		JOIN course c ON sc.cid = c.id
		JOIN (SELECT id FROM teacher WHERE `name` = '李明' ) t ON t.id = c.tid
		GROUP BY s.id, s.`name`
		HAVING COUNT(*) = (SELECT COUNT(*) FROM course JOIN (SELECT id FROM teacher WHERE `name` = '李明') t ON t.id = course.tid);


-- 文心一言

WITH Teacher AS (
    SELECT id 
    FROM teacher 
    WHERE `name` = '李明'
),
CoursesByTeacher AS (
    SELECT c.id AS cid
    FROM course c
    JOIN Teacher t ON c.tid = t.id
),
StudentCourseCounts AS (
    SELECT s.id AS sid, COUNT(sc.cid) AS course_count
    FROM student s
    JOIN score sc ON s.id = sc.sid
    JOIN CoursesByTeacher ct ON sc.cid = ct.cid
    GROUP BY s.id
),
TeacherCourseCount AS (
    SELECT COUNT(*) AS total_course_count
    FROM CoursesByTeacher
)
SELECT sc.sid AS id, s.name
FROM StudentCourseCounts sc
JOIN student s ON sc.sid = s.id
WHERE sc.course_count = (SELECT total_course_count FROM TeacherCourseCount);


-- 第七题-查询学过编号为01的课程并且也学过编号为02的课程的学生的学号和姓名(重要)

SELECT student.id, student.`name` FROM student
		JOIN (SELECT sid FROM score WHERE cid = '1') a ON a.sid = student.id
		JOIN (SELECT sid FROM score WHERE cid = '2') b ON b.sid = student.id;



-- 第七题-查询学过编号为01的课程或者学过编号为02的课程的学生的学号和姓名(重要)

SELECT student.id, student.`name`,course.`name` FROM student
		JOIN (SELECT sid,cid FROM score) a ON a.sid = student.id
		JOIN course ON course.id = a.cid  WHERE cid = '1' OR cid = '2';

SELECT student.id, student.`name`, a.`name` FROM student
		JOIN (SELECT sid, course.`name` FROM score JOIN course ON course.id = score.cid  WHERE cid = '1' OR cid = '2' ) a ON a.sid = student.id;

-- 对一个学生有多门选课时,只显示一次名称

--  无法达成效果
-- DISTINCT关键字的使用方式有一点小瑕疵。在SQL中,DISTINCT是用来对整个结果集进行去重的,而不是单独对某一个字段进行去重。 
SELECT DISTINCT(student.id), student.`name`, a.`name` FROM student
		JOIN (SELECT sid, course.`name` FROM score JOIN course ON course.id = score.cid  WHERE cid = '1' OR cid = '2' ) a ON a.sid = student.id;
		
-- GROUP BY
SELECT DISTINCT(student.id), student.`name`, GROUP_CONCAT(a.`name`) '所选科目' FROM student
		JOIN (SELECT sid, course.`name` FROM score JOIN course ON course.id = score.cid  WHERE cid = '1' OR cid = '2' ) a ON a.sid = student.id
		GROUP BY student.id, student.`name`;


-- 第八题-查询课程编号为02的总成绩

SELECT course.id, course.`name` , SUM(score) FROM score
		JOIN course ON score.cid = course.id
		GROUP BY  course.id,course.`name`;
	

-- 第九题-查询所有课程成绩小于60分的学生的学号和姓名
SELECT student.id, student.`name`, GROUP_CONCAT(score.score SEPARATOR "    ") '所有成绩' FROM student
		JOIN score ON score.sid = student.id
		GROUP BY student.id, student.`name`;
		

SELECT DISTINCT student.id,student.name FROM student
		RIGHT JOIN score ON score.sid = student.id
		WHERE student.id NOT IN (
			SELECT student.id FROM student 
					JOIN(SELECT sid FROM score	WHERE score.score >= 60) a ON a.sid = student.id 
);
		
		
-- 文心一言
-- MAX 函数的使用, ok ...

-- 不考虑没选课
SELECT student.id, student.name
FROM student
LEFT JOIN score ON student.id = score.sid
GROUP BY student.id, student.name
HAVING MAX(score.score) < 60;

-- 没选课的学生
SELECT student.id, student.name
FROM student
LEFT JOIN score ON student.id = score.sid
GROUP BY student.id, student.name
HAVING COUNT(score.score) = 0;


-- 考虑没有选课的学生
SELECT student.id, student.name
FROM student
LEFT JOIN score ON student.id = score.sid
GROUP BY student.id, student.name
HAVING COALESCE(MAX(score.score), -9999) < 60; -- 使用一个远低于任何可能分数的值(如-9999)作为没有分数时的默认值


-- 第十课-查询没有学全所有课的学生的学号和姓名(重点)
-- 略过,GROUP BY 通过数目比对


-- 第十一题-查询至少有一门课与学号为01的学生所学课程相同的学生的学号和姓名(重点)

SELECT DISTINCT student.id, student.`name` FROM student
		JOIN score ON student.id = score.sid
		WHERE score.cid in ( SELECT score.cid FROM score WHERE score.sid = 1 ) AND student.id <> 1;
		
		
-- 第十二题-查询和01号同学所学课程完全相同的其他同学的学号 (重点)

SELECT * FROM student
		WHERE student.id IN (
			--  选课数目与1号同学选课数目相同		
			SELECT score.sid FROM score
					GROUP BY score.sid 
					HAVING COUNT(score.cid) = (SELECT COUNT(DISTINCT score.cid) FROM score WHERE score.sid = 12)
		) AND 
		student.id NOT IN (
			-- 选择了1号同学不同的科目 		
				SELECT score.sid FROM score
						WHERE score.cid NOT IN (SELECT score.cid FROM score WHERE score.sid = 12)		
		)
		AND student.id != 12;






-- 每位同学的选课情况
SELECT student.id, student.name, GROUP_CONCAT(course.`name` SEPARATOR "  ") FROM student 
		LEFT JOIN score ON score.sid = student.id
		JOIN course ON course.id = score.cid
		GROUP BY student.id, student.`name`;


-- 每门课程的选课学生
SELECT course.id, course.`name`, GROUP_CONCAT(student.`name` SEPARATOR " ")FROM course
		LEFT JOIN score ON score.cid = course.id
		JOIN student ON student.id = score.sid
		GROUP BY course.id, course.`name`;
		
	
-- 第十五题-(13题前面有重复,14题没有)查询两门及其以上不及格课程的同学的学号姓名及其平均成绩(重点)

SELECT student.id, student.name, ROUND(AVG(score.score), 2) FROM student 
		JOIN score ON student.id = score.sid
		WHERE student.id IN (
				SELECT score.sid FROM score 
					WHERE score.score < 60
					GROUP BY score.sid
					HAVING COUNT(score.score) >= 2
		)
		GROUP BY student.id;
	
	
-- 第十六题-检索01课程分数小于60,按分数降序排列的学生信息
SELECT student.*, sc.score FROM student
		RIGHT JOIN (SELECT sid, score FROM score WHERE score.cid = 1) sc ON sc.sid = student.id
		WHERE sc.score < 60
		ORDER BY sc.score DESC;


-- 第十七题-(case when)按平均成绩从高到低显示所有学生的所有课程的成绩以及平均成绩(重点 )

SELECT student.id, student.`name`, ROUND(AVG(COALESCE(score.score, 0)), 2)  '平均成绩', GROUP_CONCAT(COALESCE(score.score, 0) SEPARATOR " 、 ") FROM student
			LEFT JOIN score ON score.sid = student.id
			GROUP BY student.id, student.`name`;
			

-- max 考虑补考情况,一门课两次成绩
SELECT student.id, student.`name`, ROUND(AVG(score.score), 2) '平均成绩', 
		MAX(CASE WHEN score.cid = 1 THEN score.score ELSE NULL END) '语文',
		MAX(CASE WHEN score.cid = 2 THEN score.score ELSE NULL END) '数学', 
		MAX(CASE WHEN score.cid = 3 THEN score.score ELSE NULL END) '英语'  FROM student		
			LEFT JOIN score ON score.sid = student.id
			GROUP BY student.id, student.`name`
			ORDER BY AVG(score.score) DESC;


-- 第十八题-查询各科成绩最高分,最低分,平均分,及格率,中等率,优良率,优秀率(重点)

SELECT course.`name`, MAX(score.score), MIN(score.score), AVG(score.score), COUNT(CASE WHEN score.score >= 60 THEN 1 ELSE NULL END) / COUNT(score.score)  FROM score
		LEFT JOIN course ON course.id = score.cid
		GROUP BY score.cid, course.`name`;

 
-- 查询中位数
-- 注意:这个查询是为了演示目的而编写的,并且可能不适用于所有数据库系统。
-- 它使用了字符串聚合来模拟成绩列表,这可能会导致性能问题和精度损失。
-- 在实际生产环境中,建议使用数据库特定的功能或临时表来计算中位数。

-- TODO


-- 第十九题-按各科成绩进行排序,并显示排名(row_number,rank,dense_rank)

SELECT course.`name`, GROUP_CONCAT(score.score ORDER BY score.score) FROM student
		LEFT JOIN score ON score.sid = student.id
		JOIN course ON course.id = score.cid
		GROUP BY score.cid, course.`name`

		
-- ROW_NUMBER() 为每个学生的成绩分配一个唯一的序号,这个序号在每个课程内部是唯一的,并且是根据成绩降序排列的。
-- RANK()  如果有两个学生的成绩相同,他们将获得相同的排名,但下一个学生的排名将跳过(例如,1, 2, 2, 4)。
-- DENSE_RANK() 在这个排名中,如果有两个学生的成绩相同,他们将获得相同的排名,并且下一个学生的排名不会跳过(例如,1, 2, 2, 3)。

		
-- 按个人征信credit对学生进行排名
SELECT  ROW_NUMBER() over (ORDER BY credit DESC) , student.* FROM student; 


-- 分区函数  PARTITION BY
-- <窗口函数> over ( partition by<用于分组的列名> order by <用于排序的列名>)

-- 窗口函数
-- 专用窗口函数: rank(), dense_rank(), row_number()
-- 聚合函数 : sum(), max(), min(), count(), avg() 等

-- 专用窗口函数
-- over(partition by type order by price desc)
-- 先对 type 中相同的进行分区,在 type 中相同的情况下对 price 进行排序


-- 每个学生的科目成绩排序
SELECT student.`name`, course.`name`  '科目', 
		RANK() over(PARTITION BY score.sid ORDER BY score.score DESC) '排名', score.score FROM student 
		JOIN score ON score.sid = student.id
		JOIN course ON course.id = score.cid;
		
		
-- 聚合函数作为窗口函数

-- 窗口内的累计总分,实际使用场景???
-- TODO
SELECT student.`name`, course.`name`  '科目', 
		SUM(score.score) over(PARTITION BY score.sid ORDER BY score.score DESC) '排名', score.score FROM student 
		JOIN score ON score.sid = student.id
		JOIN course ON course.id = score.cid;



-- 科目名次
SELECT DENSE_RANK() OVER (PARTITION BY score.cid ORDER BY ROUND(score.score) DESC) '名次',
			course.name '科目', student.`name` '学生姓名', ROUND(score.score) '分数' FROM score
		JOIN course ON course.id = score.cid
		JOIN student ON student.id =  score.sid;
		

-- 第二十题-查询学生的总成绩并进行排名

-- 平均成绩,总成绩科目数相差太多,无意义
SELECT RANK() over (ORDER BY AVG(score.score)  DESC), student.`name`, AVG(score.score) AS avg_score FROM student
		JOIN score ON score.sid = student.id
		GROUP BY score.sid, student.`name`
		ORDER BY avg_score DESC;
		
-- 	未选课视为0分
SELECT RANK() over (ORDER BY AVG(COALESCE(score.score, 0))  DESC), student.`name`, AVG(COALESCE(score.score, 0)) AS avg_score FROM student
		LEFT JOIN score ON score.sid = student.id
		GROUP BY student.id, student.`name`
		ORDER BY avg_score DESC;
		
-- 第二十一题-查询不同老师所教不同课程平均分从高到低显示


SELECT teacher.`name`, AVG(CASE WHEN score.cid = 1 THEN score.score ELSE 0 END) '语文平均成绩', GROUP_CONCAT(DISTINCT(course.`name`)) , AVG(score.score)   FROM teacher
		LEFT JOIN course ON course.tid = teacher.id 
		JOIN score ON score.cid = course.id
	GROUP BY teacher.id, teacher.`name`, score.cid;
	
	
	
-- 第二十二题-查询所有课程的成绩第2名到第3名的学生信息及该课程成绩(重点)
-- TODO
SELECT * FROM (
		SELECT RANK() over( PARTITION BY course.id ORDER BY score.score DESC) as rk, student.`name` as sname, course.`name` as cname, score.score FROM student
				LEFT JOIN score ON score.sid = student.id
				JOIN course ON course.id = score.cid
) temp
WHERE temp.rk in (2,3);




-- 第二十四题-查询学生平均成绩及其名次
SELECT ROW_NUMBER() over (ORDER BY rk.avg_sc DESC), rk.sname, rk.avg_sc		
		FROM(
				SELECT 	student.`name` as sname, AVG(score.score) avg_sc FROM student 
						LEFT JOIN score ON score.sid = student.id
						GROUP BY student.id, student.`name`
						ORDER BY  avg_sc DESC
		) rk ;


-- 第二十六题 -(第25题与第22题类似)查询每门课程被选修的学生数
SELECT course.`name`, COUNT(score.sid) FROM course
		LEFT JOIN score ON score.cid = course.id
		GROUP BY course.id;


-- 第二十七题 - 查询出只有两门课程的全部学生的学号和姓名

SELECT student.`name`, GROUP_CONCAT(course.`name`) FROM student
		JOIN score ON score.sid = student.id
		JOIN course ON course.id  = score.cid
		GROUP BY score.sid, student.`name`
		HAVING COUNT(DISTINCT score.cid) = 2;
		
		
		
-- 第二十八题 - 查询男生、女生人数

SELECT student.sex, COUNT(student.id) FROM student
		GROUP BY student.sex;

-- 第二十九题-查询名字中含有风字的学生信息

SELECT * FROM student
		WHERE student.`name` LIKE '%雪%';


-- 第三十一题-(30题没有)查询1990年出生的学生名单(重点)


SELECT * FROM student
		WHERE YEAR(birth) = 1994;



-- 第三十二题-查询平均成绩大于等于85的所有学生的学号、姓名和平均成绩


SELECT student.id, student.`name`, AVG(score.score) FROM student
		LEFT JOIN score ON score.sid = student.id
		GROUP BY student.id, student.`name`
		HAVING AVG(score.score) > 70;


-- 第三十三题-查询每门课程的平均成绩,结果按平均成绩升序排序,平均成绩相同时,按课程号降序排列


SELECT course.`name`,AVG(score.score) AS avg_sc, score.cid FROM score
		LEFT JOIN course ON course.id = score.cid
		GROUP BY score.cid, course.`name`
		ORDER BY avg_sc ASC, score.cid DESC;
		
		
-- 第三十四题-查询课程名称为数学,且分数低于60的学生姓名和分数


SELECT * FROM student 
		LEFT JOIN score ON score.sid = student.id
		WHERE score.cid = (SELECT course.id FROM course WHERE course.`name` = '数学') AND score.score < 60;
		
		
-- 第三十五题-查询所有学生的课程及分数情况(重点)
-- 第三十六题-查询课程成绩在70分以上课程名称,分数和学生姓名
-- 第三十七题-查询不及格的课程并按课程号从大到小排列
-- 第三十八题-查询课程编号为03且课程成绩在80分以上的学生的学号和姓名
-- 第三十九题-求每门课程的学生人数

-- 第四十题-查询选修张三老师所授课程的学生中成绩最高的学生姓名及其成绩

SELECT * FROM student
		JOIN score ON score.sid = student.id
		JOIN course ON course.id = score.cid
		WHERE course.tid = (SELECT id FROM teacher WHERE teacher.`name` = '赵敏')
		ORDER BY score.score;
		
-- 好吧,一个老师一门课		
SELECT teacher.id, GROUP_CONCAT(course.`name`) FROM teacher
		LEFT JOIN course ON course.id = teacher.id
		GROUP BY teacher.id;
		
		
-- 第四十一题-查询不同课程成绩相同的学生的学生编号、课程编号、学生成绩

SELECT ROUND(score.score),GROUP_CONCAT(course.`name`), GROUP_CONCAT(student.`name`) FROM student
		LEFT JOIN score ON score.sid = student.id
		JOIN course ON course.id = score.cid
		GROUP BY ROUND(score.score)
		HAVING COUNT(DISTINCT score.cid) > 1;
		

		
-- 第四十三题 -(42题有类似题)统计每门课程的学生选修人数
-- 第四十四题-检索至少选修两门课程的学生学号
-- 第四十五题-查询选修了全部课程的学生信息


-- 第四十六题-查询各学生的年龄

-- 日期操作
SELECT name, TIMESTAMPDIFF(YEAR, birth, CURDATE())  as age FROM student ORDER BY age; 



-- 第四十七题-查询没学过张三老师讲授的任一门课程的学生姓名
-- 第四十八题-查询下周过生日的同学

SELECT * FROM student ORDER BY MONTH(birth);

-- 查找下周过生日的学生
SELECT * FROM student WHERE WEEK(NOW())+2 = WEEK(birth);
SELECT * FROM student WHERE WEEK(NOW())+1 = WEEK(CONCAT(YEAR(NOW()),"-",SUBSTR(birth,6,5)));



-- 第四十九题-查询本月过生日的人
-- 第五十题-查询下一个月过生日的同学
-- 跨年
-- 查到下个月过生日的学生
SELECT * FROM student WHERE MONTH(NOW()) = MONTH(birth);
SELECT * FROM student WHERE MONTH(birth) - MONTH(NOW()) = 1;
SELECT * FROM student WHERE MONTH(birth) = CASE WHEN MONTH(NOW()) = 12 THEN 1 ELSE MONTH(NOW()) + 1 END;




-- 逻辑错误
-- 在MySQL中,使用TIMESTAMPDIFF函数计算两个日期之间的月份差异时,函数会返回两个日期之间完整的月份数。
SELECT TIMESTAMPDIFF(MONTH, '2024-01-31', '2024-02-29');
SELECT TIMESTAMPDIFF(MONTH, '2024-01-31', '2024-03-01');

SELECT CONCAT(YEAR(CURDATE()), "-", SUBSTR("1994-12-06", 6,5 ));
SELECT * FROM student WHERE TIMESTAMPDIFF(MONTH, STR_TO_DATE(CONCAT(YEAR(CURDATE()), "-", SUBSTR(birth, 6, 5)),"%Y-%m-%d"), CURDATE())=10;

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/927951.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Redis(配置文件属性解析)

一、tcp-backlog深度解析 tcp-backlog是一个TCP连接的队列&#xff0c;主要用于解决高并发场景下客户端慢连接问题。配置文件中的“511”就是队列的长度&#xff0c;对联与TCP的三次握手有关&#xff0c;不同的linux内核&#xff0c;backlog队列中存放的元素&#xff08;客户端…

Vue3 脚手架扩展

当 yarn dev 运行成功后&#xff0c;我们继续添加扩展 首先我们要安装一些依赖 其中的vue-router和vuex安装最新版的就行&#xff0c;因为项目是vue3 element-plus和less&#xff0c;less-loader最好按照我这个版本来下载 element-plus是一个vue常用的ui组件库 element-plus/…

TCP/IP协议簇自学笔记

摘抄于大学期间记录在QQ空间的一篇自学笔记&#xff0c;当前清理空间&#xff0c;本来想直接删除掉的&#xff0c;但是感觉有些舍不得&#xff0c;因此先搬移过来。 曾经&#xff0c;我只知道socket函数能进行网络间数据的通信&#xff0c;知道tcp/ip协议也是用来进行网络数据…

AI开发:逻辑回归 - 实战演练- 垃圾邮件的识别(二)

接上一篇AI开发&#xff1a;逻辑回归 - 实战演练- 垃圾邮件的识别&#xff08;一&#xff09; new_email 无论为什么文本&#xff0c;识别结果几乎都是垃圾邮件,因此我们需要对源码的逻辑进行梳理一下&#xff1a; 在代码中&#xff0c;new_email 无论赋值为何内容都被识别为…

字符串处理(二)

第1题 篮球比赛 查看测评数据信息 学校举行篮球比赛&#xff0c;请设计一个计分系统统计KIN、WIN两队分数&#xff0c;并输出分数和结果&#xff01; 如果平分就输出‘GOOD’&#xff0c;否则输出获胜队名&#xff01; 输入格式 输入数据共n1行&#xff0c; 第1行n&#xf…

【数据库系列】Liquibase 与 Flyway 的详细对比

在现代软件开发中&#xff0c;数据库版本控制是一个至关重要的环节。为了解决数据库迁移和变更管理的问题&#xff0c;开发者们通常会使用工具&#xff0c;如 Liquibase 和 Flyway。本文将对这两个流行的数据库迁移工具进行详细比较&#xff0c;从基础概念、原理、优缺点到使用…

企业品牌曝光的新策略:短视频矩阵系统

企业品牌曝光的新策略&#xff1a;短视频矩阵系统 在当今数字化时代&#xff0c;短视频已经渗透到我们的日常生活之中&#xff0c;成为连接品牌与消费者的关键渠道。然而&#xff0c;随着平台于7月20日全面下线了短视频矩阵的官方接口&#xff0c;许多依赖于此接口的小公司和内…

PostgreSQL最常用数据类型-重点说明自增主键处理

简介 PostgreSQL提供了非常丰富的数据类型&#xff0c;我们平常使用最多的基本就3类&#xff1a; 数字类型字符类型时间类型 这篇文章重点介绍这3中类型&#xff0c;因为对于高并发项目还是推荐&#xff1a;尽量使用简单类型&#xff0c;把运算和逻辑放在应用中&#xff0c;…

做异端中的异端 -- Emacs裸奔之路4: 你不需要IDE

确切地说&#xff0c;你不需要在IDE里面编写或者阅读代码。 IDE用于Render资源文件比较合适&#xff0c;但处理文本&#xff0c;并不划算。 这的文本文件&#xff0c;包括源代码&#xff0c;配置文件&#xff0c;文档等非二进制文件。 先说说IDE带的便利: 函数或者变量的自动…

ospf协议(动态路由协议)

ospf基本概念 定义 OSPF 是典型的链路状态路由协议&#xff0c;是目前业内使用非常广泛的 IGP 协议之一。 目前针对 IPv4 协议使用的是 OSPF Version 2 &#xff08; RFC2328 &#xff09;&#xff1b;针对 IPv6 协议使用 OSPF Version 3 &#xff08; RFC2740 &#xff09;。…

【热门主题】000072 分布式数据库:开启数据管理新纪元

前言&#xff1a;哈喽&#xff0c;大家好&#xff0c;今天给大家分享一篇文章&#xff01;并提供具体代码帮助大家深入理解&#xff0c;彻底掌握&#xff01;创作不易&#xff0c;如果能帮助到大家或者给大家一些灵感和启发&#xff0c;欢迎收藏关注哦 &#x1f495; 目录 【热…

Python 3 教程第33篇(MySQL - mysql-connector 驱动)

Python MySQL - mysql-connector 驱动 MySQL 是最流行的关系型数据库管理系统&#xff0c;如果你不熟悉 MySQL&#xff0c;可以阅读我们的 MySQL 教程。 本章节我们为大家介绍使用 mysql-connector 来连接使用 MySQL&#xff0c; mysql-connector 是 MySQL 官方提供的驱动器。…

ENSP IPV6-over-IPV4

IPv6是网络层协议的第二代标准协议&#xff0c;一个IPv6地址同样可以分为网络前缀和主机ID两个部分。 可以将IPV4的网络看成IPV6的承载网&#xff0c;只有IPv4网络是连通的&#xff0c;则IPv6网络才有可能连通。所以配置的时候需要先配置IPv4网络的路由功能&#xff0c;再配IP…

《数据挖掘:概念、模型、方法与算法(第三版)》

嘿&#xff0c;数据挖掘的小伙伴们&#xff01;今天我要给你们介绍一本超级实用的书——《数据挖掘&#xff1a;概念、模型、方法与算法》第三版。这本书是数据挖掘领域的经典之作&#xff0c;由该领域的知名专家编写&#xff0c;系统性地介绍了在高维数据空间中分析和提取大量…

53 基于单片机的8路抢答器加记分

目录 一、主要功能 二、硬件资源 三、程序编程 四、实现现象 一、主要功能 首先有三个按键 分别为开始 暂停 复位&#xff0c;然后八个选手按键&#xff0c;开机显示四条杠&#xff0c;然后按一号选手按键&#xff0c;数码管显示&#xff13;&#xff10;&#xff0c;这…

从零开始写游戏之斗地主-网络通信

在确定了数据结构后&#xff0c;原本是打算直接开始写斗地主的游戏运行逻辑的。但是突然想到我本地写出来之后&#xff0c;也测试不了啊&#xff0c;所以还是先写通信模块了。 基本框架 在Java语言中搞网络通信&#xff0c;那么就得请出Netty这个老演员了。 主要分为两个端&…

Logistic Regression(逻辑回归)、Maximum Likelihood Estimatio(最大似然估计)

Logistic Regression&#xff08;逻辑回归&#xff09;、Maximum Likelihood Estimatio&#xff08;最大似然估计&#xff09; 逻辑回归&#xff08;Logistic Regression&#xff0c;LR&#xff09;逻辑回归的基本思想逻辑回归模型逻辑回归的目标最大似然估计优化方法 逻辑回归…

数据类型.

数据类型分类 数值类型 tinyint类型 以tinyint为例所有数值类型默认都是有符号的&#xff0c;无符号的需要在后面加unsignedtinyint的范围在-128~127之间无符号的范围在0~255之间(类比char) create database test_db; use test_db;建表时一定要跟着写上属性 mysql> creat…

IDEA使用HotSwapHelper进行热部署

目录 前言JDK1.8特殊准备DECVM安装插件安装与配置参考文档相关下载 前言 碰到了一个项目&#xff0c;用jrebel启动项目时一直报错&#xff0c;不用jrebel时又没问题&#xff0c;找不到原因&#xff0c;又不想放弃热部署功能 因此思考能否通过其他方式进行热部署&#xff0c;找…

机器学习算法(六)---逻辑回归

常见的十大机器学习算法&#xff1a; 机器学习算法&#xff08;一&#xff09;—决策树 机器学习算法&#xff08;二&#xff09;—支持向量机SVM 机器学习算法&#xff08;三&#xff09;—K近邻 机器学习算法&#xff08;四&#xff09;—集成算法 机器学习算法&#xff08;五…