学习记录379@MySQL经典练习50题

CREATE DATABASE stumsc;
CREATE TABLE student(
	sno VARCHAR(10) PRIMARY KEY,
	sname VARCHAR(20),
	sage INT,
	ssex VARCHAR(5)
);
CREATE TABLE teacher(
	tno VARCHAR(10) PRIMARY KEY,
	tname VARCHAR(20)
);
CREATE TABLE course(
	cno VARCHAR(10),
	cname VARCHAR(20),
	tno VARCHAR(20),
	PRIMARY KEY (cno,tno)
);
CREATE TABLE sc(
	sno VARCHAR(10),
	cno VARCHAR(10),
	score DOUBLE(4,2),
	PRIMARY KEY (sno,cno)
);
/*******初始化学生表的数据******/
INSERT INTO student VALUES ('s001','张三',23,'男');
INSERT INTO student VALUES ('s002','李四',23,'男');
INSERT INTO student VALUES ('s003','吴鹏',25,'男');
INSERT INTO student VALUES ('s004','琴沁',20,'女');
INSERT INTO student VALUES ('s005','王丽',20,'女');
INSERT INTO student VALUES ('s006','李波',21,'男');
INSERT INTO student VALUES ('s007','刘玉',21,'男');
INSERT INTO student VALUES ('s008','萧蓉',21,'女');
INSERT INTO student VALUES ('s009','陈萧晓',23,'女');
INSERT INTO student VALUES ('s010','陈美',22,'女');
COMMIT;
/******************初始化教师表***********************/
INSERT INTO teacher VALUES ('t001', '刘阳');
INSERT INTO teacher VALUES ('t002', '谌燕');
INSERT INTO teacher VALUES ('t003', '胡明星');
COMMIT;
/***************初始化课程表****************************/
INSERT INTO course VALUES ('c001','J2SE','t002');
INSERT INTO course VALUES ('c002','Java Web','t002');
INSERT INTO course VALUES ('c003','SSH','t001');
INSERT INTO course VALUES ('c004','Oracle','t001');
INSERT INTO course VALUES ('c005','SQL SERVER 2005','t003');
INSERT INTO course VALUES ('c006','C#','t003');
INSERT INTO course VALUES ('c007','JavaScript','t002');
INSERT INTO course VALUES ('c008','DIV+CSS','t001');
INSERT INTO course VALUES ('c009','PHP','t003');
INSERT INTO course VALUES ('c010','EJB3.0','t002');
COMMIT;
/***************初始化成绩表***********************/
INSERT INTO sc VALUES ('s001','c001',78.9);
INSERT INTO sc VALUES ('s002','c001',80.9);
INSERT INTO sc VALUES ('s003','c001',81.9);
INSERT INTO sc VALUES ('s004','c001',60.9);
INSERT INTO sc VALUES ('s001','c002',82.9);
INSERT INTO sc VALUES ('s002','c002',72.9);
INSERT INTO sc VALUES ('s003','c002',81.9);
INSERT INTO sc VALUES ('s001','c003',59.0);
COMMIT;
-- 查询学生表所有信息
SELECT * FROM student;
-- 查询教师表所有信息
SELECT * FROM teacher;
-- 查询课程表的所有信息
SELECT * FROM course;
-- 查询成绩表的所有信息
SELECT * FROM sc;

1、查询“c001”课程比“c002”课程成绩高的所有学生的学号;

SELECT DISTINCT sc1.sno
FROM sc sc1
JOIN sc sc2
ON sc1.sno=sc2.sno
WHERE (sc1.cno='c001' AND sc2.cno='c002' AND sc1.score>sc2.score) 


2、查询平均成绩大于60 分的同学的学号和平均成绩;

SELECT sno,AVG(IFNULL(score,0)) '平均成绩'
FROM sc
GROUP BY sno
HAVING AVG(IFNULL(score,0))>60


3、查询所有同学的学号、姓名、选课数、总成绩;

SELECT student.sno,student.sname,COUNT(DISTINCT sc.cno) '选课数',SUM(IFNULL(score,0)) '总成绩'
FROM student
LEFT JOIN sc
ON student.sno=sc.sno
GROUP BY student.sno
ORDER BY student.sno

4、查询姓“刘”的老师的个数;

SELECT COUNT(tno) '姓刘的老师的个数'
FROM teacher
WHERE tname like '刘%'

5*****查询没学过“谌燕”老师课的同学的学号、姓名;
-- 必须要先求学过的,再剔除
-- 不能用直接not in
-- SELECT student.sno,student.sname
-- FROM student
-- JOIN sc
-- ON student.sno=sc.sno
-- WHERE sc.cno NOT IN(
-- 		SELECT course.cno
-- 		FROM course
-- 		JOIN teacher
-- 		ON course.tno=teacher.tno
-- 		WHERE teacher.tname='谌燕'
-- 	)

SELECT student.sno,student.sname
FROM student
WHERE student.sno NOT IN(
-- 先选出学过的,再剔除
	SELECT DISTINCT student.sno
	FROM student
	JOIN sc
	ON student.sno=sc.sno
	WHERE sc.cno IN(
		SELECT course.cno
		FROM course
		JOIN teacher
		ON course.tno=teacher.tno
		WHERE teacher.tname='谌燕'
	)
)


6*****查询学过“c001”并且也学过编号“c002”课程的同学的学号、姓名;
-- 这种既做了什么又做了什么 一般都要连接表,一张表,当作两张表来连接

SELECT DISTINCT student.sno,student.sname
FROM student
JOIN sc sc1
ON student.sno=sc1.sno
JOIN sc sc2
ON sc1.sno=sc2.sno
WHERE (sc1.cno='c001' AND sc2.cno='c002')



7*****查询学过“谌燕”老师所教的所有课的同学的学号、姓名;

SELECT DISTINCT student.sno,student.sname
FROM student
WHERE student.sno IN(
-- in中查询满足条件的学号
	SELECT sc.sno
	FROM sc 
	JOIN course
	ON course.cno=sc.cno
	JOIN teacher
	ON course.tno=teacher.tno
	WHERE teacher.tname='谌燕'
	GROUP BY sc.sno
-- 	HAVING判断分组下学生学的谌燕老师得课程数量是否和谌燕老师教的课程总数相同
	HAVING COUNT(DISTINCT sc.cno)=(
-- 	子查询查谌燕老师教得课程总数
		SELECT COUNT(course.cno)
		FROM course
		LEFT JOIN teacher
		ON course.tno=teacher.tno
		WHERE teacher.tname='谌燕'
	)
)

8、查询课程编号“c002”的成绩比课程编号“c001”课程低的所有同学的学号、姓名;

SELECT DISTINCT student.sno,student.sname
FROM student
JOIN sc sc1
ON student.sno=sc1.sno
JOIN sc sc2
ON sc1.sno=sc2.sno
WHERE (sc1.cno='c001' AND sc2.cno='c002' AND sc2.score<sc1.score ) 

9、查询所有课程成绩小于60 分的同学的学号、姓名;
SELECT student.sno,student.sname
FROM student
LEFT JOIN sc
ON student.sno=sc.sno
GROUP BY student.sno
HAVING MAX(IFNULL(score,0))<60



10、查询没有学全所有课的同学的学号、姓名;
SELECT student.sno,student.sname
FROM student
LEFT JOIN sc
ON student.sno=sc.sno
GROUP BY student.sno
HAVING COUNT(sc.cno)<
(SELECT COUNT(course.cno)
FROM course)


11、查询至少有一门课与学号为“s001”的同学所学相同的同学的学号和姓名;
SELECT student.sno,student.sname
FROM student
LEFT JOIN sc
ON student.sno=sc.sno
WHERE sc.cno IN(
	SELECT sc.cno
	FROM sc
	WHERE sc.sno='s001'
) AND student.sno!='s001'


12*****查询至少学过学号为“s001”同学所有课的其他同学学号和姓名;
-- 忽略
)

13*****把“SC”表中“谌燕”老师教的课的成绩都更改为此课程的平均成绩;
SELECT sc.sno,sc.cno,
CASE
WHEN sc.cno IN(
	SELECT sc.cno
	FROM sc
	JOIN course
	ON sc.cno=course.cno
	JOIN teacher
	ON teacher.tno=course.tno
	WHERE teacher.tname='谌燕'
) 
THEN 
	(SELECT AVG(IFNULL(sc2.score,0))
	FROM sc sc2
	GROUP BY sc2.cno
	HAVING sc2.cno=sc.cno
	)
ELSE sc.score
END 'score'
FROM sc



14*****查询和“s001”号的同学学习的课程完全相同的其他同学学号和姓名;

SELECT student.sno,student.sname
FROM student
WHERE student.sno IN(
	select sno from sc where sno not in(
	(select sno from sc where cno not  in(
	select cno from sc where sno='s001'))) and sno!='s001'
	group by sno having 
	count(1)=(select count(1) FROM sc WHERE sno='s001')
)


15、删除学习“谌燕”老师课的SC 表记录;

DELETE FROM sc
WHERE sc.cno IN(
	SELECT sc.cno
	FROM sc
	JOIN course
	ON sc.cno=course.cno
	JOIN teacher
	ON teacher.tno=course.tno
	WHERE teacher.tname='谌燕'
)


16、向SC 表中插入一些记录,这些记录要求符合以下条件:没有上过编号“c002”课程的同学学号、“c002”号课的平均成绩;
-- 不对,题目有问题,忽略
 

17、查询各科成绩最高和最低的分:以如下形式显示:课程ID,最高分,最低分
SELECT sc.cno 课程ID, MAX(IFNULL(sc.score,0)) '最高分',MIN(IFNULL(sc.score,0)) '最低分'
FROM sc
GROUP BY sc.cno

18*****按各科平均成绩从低到高和及格率的百分数从高到低顺序

-- ,SUM(IF(sc.score>60,1,0))SUM(CASE WHEN sc.score>60 THEN 1 ELSE 0 END)效果一样
SELECT sc.cno,AVG(IFNULL(sc.score,0)) '平均成绩',SUM(IF(sc.score>=60,1,0)) '及格人数',COUNT(IFNULL(sc.score,0)) '总人数',
	SUM(CASE WHEN sc.score>=60 THEN 1 ELSE 0 END)/COUNT(SC.score) '及格率'
FROM sc
GROUP BY sc.cno
ORDER BY 平均成绩 ASC,及格率 DESC

19、查询不同老师所教不同课程平均分从高到低显示

SELECT teacher.tname,course.cname,sc.cno, AVG(IFNULL(sc.score,0)) '平均分'
FROM teacher
LEFT JOIN course
ON teacher.tno=course.tno
LEFT JOIN sc
ON sc.cno=course.cno
GROUP BY teacher.tname,course.cno
ORDER BY 平均分

20*****统计各科成绩,各分数段人数:课程ID,课程名称,[100-85],[85-70],[70-60],[ <60]


SELECT sc.cno,course.cname,
SUM(CASE WHEN sc.score<60 THEN 1 ELSE 0 END) '[ <60]',
SUM(CASE WHEN sc.score>=60 AND sc.score<70 THEN 1 ELSE 0 END) '[70-60]',
SUM(CASE WHEN sc.score>=70 AND sc.score<85 THEN 1 ELSE 0 END) '[85-70]',
SUM(CASE WHEN sc.score>=85 AND sc.score<100 THEN 1 ELSE 0 END) '[100-85]'
FROM sc
JOIN course
ON sc.cno=course.cno
GROUP BY sc.cno

21**********查询各科成绩前三名的记录:(不考虑成绩并列情况)
-- 思路超级巧妙,但是如果有并列的,会显示出来多条
SELECT cno,score FROM sc s1 WHERE
(SELECT COUNT(s2.score) FROM sc s2 WHERE s1.cno=s2.cno AND s2.score>s1.score)<3
ORDER BY s1.cno,s1.score DESC

22、查询每门课程被选修的学生数
SELECT course.cno,course.cname,COUNT(sc.score)
FROM course
LEFT JOIN sc
ON course.cno=sc.cno
GROUP BY course.cno


23、查询出只选修了一门课程的全部学生的学号和姓名
SELECT student.sno,student.sname
FROM student
WHERE student.sno IN(
	SELECT sc.sno
	FROM sc
	GROUP BY sc.sno
	HAVING COUNT(DISTINCT sc.cno)=1
)

24、查询男生、女生人数
SELECT
SUM(CASE WHEN ssex='男' THEN 1 ELSE 0 END) '男', 
SUM(CASE WHEN ssex='女' THEN 1 ELSE 0 END) '女' 
FROM student

25、查询姓“张”的学生名单
SELECT * 
FROM student
WHERE student.sname LIKE '张%'
26、查询同名同性学生名单,并统计同名人数
SELECT student.sname,student.ssex,COUNT(1)
FROM student
GROUP BY student.sname,student.ssex

271981 年出生的学生名单(注:Student 表中Sage 列的类型是double)
SELECT *
FROM student
WHERE TIMESTAMPDIFF(YEAR,DATE('1981-1-1'),NOW())=sage

28、查询每门课程的平均成绩,结果按平均成绩升序排列,平均成绩相同时,按课程号降序排列
SELECT AVG(IFNULL(score,0)),cno
FROM sc
GROUP BY cno
ORDER BY 1,2 DESC

29、查询平均成绩大于75 的所有学生的学号、姓名和平均成绩
SELECT student.sno,student.sname,AVG(IFNULL(score,0))
FROM student
JOIN sc
ON sc.sno=student.sno
GROUP BY sc.sno
HAVING AVG(IFNULL(score,0))>75

30、查询课程名称为“数据库”,且分数低于60 的学生姓名和分数
SELECT student.sno,student.sname,sc.score
FROM student
JOIN sc
ON sc.sno=student.sno
JOIN course
ON course.cno=sc.cno
WHERE sc.score<60 AND course.cname='数据库'

31、查询所有学生的选课情况;
SELECT student.sno,student.sname,COUNT(sc.score)
FROM student
LEFT JOIN sc
ON student.sno=sc.sno
GROUP BY student.sno

32、查询任何一门课程成绩在70 分以上的姓名、课程名称和分数;
SELECT student.sno,student.sname,course.cname,sc.score
FROM student
LEFT JOIN sc
ON student.sno=sc.sno
JOIN course
ON course.cno=sc.cno
GROUP BY sc.sno
HAVING MIN(sc.score)>70

33、查询不及格的课程,并按课程号从大到小排列
SELECT *
FROM sc
WHERE score<60
ORDER BY cno

34、查询课程编号为c001 且课程成绩在80 分以上的学生的学号和姓名;
SELECT student.sno,student.sname
FROM student
LEFT JOIN sc
ON student.sno=sc.sno
WHERE sc.cno='c001' AND sc.score>=80

35、求选了课程的学生人数
SELECT COUNT(DISTINCT sno)
FROM sc

36、查询选修“谌燕”老师所授课程的学生中,成绩最高的学生姓名及其成绩
SELECT student.sname,sc.score
FROM student
LEFT JOIN sc
ON student.sno=sc.sno
JOIN course
ON course.cno=sc.cno
JOIN teacher
ON teacher.tno=course.tno
WHERE teacher.tname='谌燕'
ORDER BY sc.score DESC
LIMIT 1
37、查询各个课程及相应的选修人数
SELECT course.cno,course.cname,COUNT(sc.score)
FROM course
JOIN sc
ON course.cno=sc.cno
GROUP BY course.cno

38*****查询不同课程成绩相同的学生的学号、课程号、学生成绩
-- 条件:同一个学生,不同课程,相同成绩
SELECT sc1.sno,sc1.cno,sc1.score
FROM sc sc1
JOIN sc sc2
ON sc1.sno=sc2.sno
AND sc1.cno!=sc2.cno AND sc1.score=sc2.score

39**********查询每门功课成绩最好的前两名
-- 如果成绩相同,也会算在里面
SELECT cno,score FROM sc s1 WHERE 
(SELECT COUNT(1) FROM sc s2 WHERE s1.cno=s2.cno AND s2.score>s1.score)<2
ORDER BY s1.cno,s1.score DESC
40、统计每门课程的学生选修人数(超过10 人的课程才统计)。要求输出课程号和选修人数,查询结果按人数降序排列,若人数相同,按课程号升序排列
SELECT course.cno,COUNT(sc.score)
FROM course
JOIN sc
ON course.cno=sc.cno
GROUP BY course.cno
HAVING COUNT(sc.score)>10
ORDER BY 2 DESC, 1

41、检索至少选修两门课程的学生学号
SELECT sno
FROM sc
GROUP BY sno
HAVING COUNT(DISTINCT cno)>=2

42、查询全部学生都选修的课程的课程号和课程名
SELECT sc.cno,course.cname
FROM sc
JOIN course
ON sc.cno=course.cno
GROUP BY sc.cno
HAVING COUNT(DISTINCT sc.sno)=(SELECT COUNT(1) FROM student)

43、查询没学过“谌燕”老师讲授的任一门课程的学生姓名

SELECT student.sname
FROM student
WHERE student.sno NOT IN(
	SELECT sc.sno
	FROM sc
	JOIN course
	ON course.cno=sc.cno
	JOIN teacher
	ON teacher.tno=course.tno
	WHERE teacher.tname='谌燕'
)



44、查询两门以上不及格课程的同学的学号及其平均成绩
SELECT sno ,AVG(IFNULL(score,0))
FROM sc
WHERE sno IN(

	SELECT sno 
	FROM sc
	WHERE score<60
	GROUP BY sno
	HAVING COUNT(DISTINCT cno)>2
)
GROUP BY sno


45、检索“c004”课程分数小于60,按分数降序排列的同学学号
SELECT sno
FROM sc
WHERE cno='c004' AND score<60

46、删除“s002”同学的“c001”课程的成绩
DELETE FROM sc
WHERE sno='s002' AND cno='c001'

其实只有46道题

你可能感兴趣的:(学习记录379@MySQL经典练习50题)