mysql查询练习

-- 选择数据库
USE testdb;

-- 删除表
DROP TABLE Student;
DROP TABLE Course;
DROP TABLE SC;
DROP TABLE Teacher;

-- 语法:
SELECT select_list    
FROM table_name   
[ WHERE search_condition ]   
[ GROUP BY group_by_expression ]   
[ HAVING search_condition ]   
[ ORDER BY order_expression [ ASC | DESC ] ] 
[LIMIT m,n] 
  
-- 示例:
-- limit 0,10是从第一条开始,取10条数据
SELECT classNo  FROM table_name  
GROUP BY classNo   
HAVING(AVG(成绩)>70) 
ORDER BY classNo  
LIMIT 0,10


-- 空值替换 IFNULL


-- 建表:
-- Student(S#,Sname,Sage,Ssex) 学生表 
-- Course(C#,Cname,T#) 课程表 
-- SC(S#,C#,score) 成绩表 
-- Teacher(T#,Tname) 教师表


-- Student(S#,Sname,Sage,Ssex) 学生表
CREATE TABLE Student(
	sid INT PRIMARY KEY,
	sname VARCHAR(20) NOT NULL DEFAULT '',
	sage INT,
	ssex VARCHAR(2)
)

-- Course(C#,Cname,T#) 课程表 
CREATE TABLE Course(
	cid INT PRIMARY KEY,
	cname VARCHAR(20) NOT NULL DEFAULT '',
	tid INT
)

-- Teacher(T#,Tname) 教师表
CREATE TABLE Teacher(
	tid INT PRIMARY KEY,
	tname VARCHAR(20) NOT NULL DEFAULT ''
)

-- SC(S#,C#,score) 成绩表 
CREATE TABLE SC(
	sid INT ,
	cid INT ,
	score INT
)



-- 学生表测试数据
INSERT INTO Student VALUES(01 , '赵雷' , 18 , '男');
INSERT INTO Student VALUES(02 , '钱电' , 19 , '男');
INSERT INTO Student VALUES(03 , '孙风' , 22 , '男');
INSERT INTO Student VALUES(04 , '李云' , 19 , '男');
INSERT INTO Student VALUES(05 , '周梅' , 20 , '女');
INSERT INTO Student VALUES(06 , '吴兰' , 19 , '女');
INSERT INTO Student VALUES(07 , '郑竹' , 21 , '女');
INSERT INTO Student VALUES(08 , '王菊' , 18 , '女');

-- 课程表测试数据
INSERT INTO Course VALUES(01 , '语文' , 02);
INSERT INTO Course VALUES(02 , '数学' , 01);
INSERT INTO Course VALUES(03 , '英语' , 03);
 
-- 教师表测试数据
INSERT INTO Teacher VALUES(01 , '张三');
INSERT INTO Teacher VALUES(02 , '李四');
INSERT INTO Teacher VALUES(03 , '王五');
INSERT INTO Teacher VALUES(04 , '李六');
 
-- 成绩表测试数据
INSERT INTO SC VALUES(01 , 01 , 80);
INSERT INTO SC VALUES(01 , 02 , 90);
INSERT INTO SC VALUES(01 , 03 , 99);
INSERT INTO SC VALUES(02 , 01 , 70);
INSERT INTO SC VALUES(02 , 02 , 60);
INSERT INTO SC VALUES(02 , 03 , 80);
INSERT INTO SC VALUES(03 , 01 , 80);
INSERT INTO SC VALUES(03 , 02 , 80);
INSERT INTO SC VALUES(03 , 03 , 80);
INSERT INTO SC VALUES(04 , 01 , 50);
INSERT INTO SC VALUES(04 , 02 , 30);
INSERT INTO SC VALUES(04 , 03 , 20);
INSERT INTO SC VALUES(05 , 01 , 76);
INSERT INTO SC VALUES(05 , 02 , 87);
INSERT INTO SC VALUES(06 , 01 , 31);
INSERT INTO SC VALUES(06 , 03 , 34);
INSERT INTO SC VALUES(07 , 02 , 89);
INSERT INTO SC VALUES(07 , 03 , 98);
INSERT INTO SC VALUES(08 , 01 , 31);
INSERT INTO SC VALUES(08 , 03 , 34);
INSERT INTO SC VALUES(08 , 02 , 89);

COMMIT;

-- Student(S#,Sname,Sage,Ssex) 学生表 
-- Course(C#,Cname,T#) 课程表 
-- SC(S#,C#,score) 成绩表 
-- Teacher(T#,Tname) 教师表

-- 1、查询“01”课程比“02”课程成绩高的所有学生的学号;
SELECT a.sid FROM (SELECT sid, score FROM sc WHERE cid=01) a,(SELECT sid ,score FROM sc WHERE cid=02) b WHERE a.score > b.score AND a.sid= b.sid;

SELECT a.sid FROM student a LEFT JOIN SC b ON b.cid=01 AND a.sid=b.sid LEFT JOIN SC c ON c.cid=02 AND a.sid=c.sid WHERE b.score>c.score;

-- 2、查询平均成绩大于60分的同学的学号和平均成绩;
SELECT sid, AVG(score) FROM sc GROUP BY sid HAVING AVG(score)>60;

-- 3、查询所有同学的学号、姓名、选课数、总成绩;
SELECT s.sid, sname, COUNT(cid), AVG(score) FROM student s LEFT JOIN sc ON s.sid = sc.sid GROUP BY sc.sid;

-- 4、查询姓“李”的老师的个数;
SELECT COUNT(DISTINCT(tname)) FROM Teacher WHERE tname LIKE '李%';

-- 5、查询没学过“王五”老师课的同学的学号、姓名;
SELECT sid, sname FROM student WHERE sid NOT IN(SELECT DISTINCT(s.sid) FROM student s, Course c, Teacher t, sc WHERE s.sid = sc.sid AND sc.cid = c.cid AND c.tid = t.tid AND t.tname = '王五'); -- 效率低

SELECT sid, sname FROM student s1 LEFT JOIN (SELECT DISTINCT(s.sid) id FROM student s, Course c, Teacher t, sc WHERE s.sid = sc.sid AND sc.cid = c.cid AND c.tid = t.tid AND t.tname = '王五') AS s2 ON s1.sid = s2.id WHERE s2.id IS NULL; -- 效率相对高

-- 6、查询学过“01”并且也学过编号“02”课程的同学的学号、姓名;
SELECT DISTINCT(s.sid), sname FROM student s, Course c, SC WHERE s.sid = sc.sid AND c.cid = sc.cid AND c.cid = 01;
SELECT DISTINCT(s.sid), sname FROM student s, Course c, SC WHERE s.sid = sc.sid AND c.cid = sc.cid AND c.cid = 02;

SELECT DISTINCT(s.sid), sname FROM student s, Course c, SC WHERE s.sid = sc.sid AND c.cid = sc.cid AND c.cid = 01 AND s.sid IN (SELECT sid FROM SC WHERE cid = 02);

-- 7、查询学过“王五”老师所教的所有课的同学的学号、姓名;
SELECT s.sid, sname FROM Student s, Course c, Teacher t, SC WHERE s.sid = sc.sid AND c.cid = sc.cid AND t.tid = c.tid AND t.tname = '王五';

-- 8、查询课程编号“002”的成绩比课程编号“001”课程低的所有同学的学号、姓名;
SELECT s.sid, sname FROM student s, (SELECT sid, score FROM SC WHERE cid = 01) sc1, (SELECT sid, score FROM SC WHERE cid = 02) sc2 WHERE sc1.sid = s.sid AND sc2.sid = s.sid AND sc1.score > sc2.score;

-- 9、查询所有课程成绩小于60分的同学的学号、姓名;
SELECT sid, sname FROM student WHERE sid NOT IN (SELECT sid FROM sc WHERE sc.score > 60);

-- 10、查询没有学全所有课的同学的学号、姓名;
SELECT sid, sname FROM student WHERE sid IN(SELECT sid FROM sc GROUP BY sid HAVING COUNT(sid) < (SELECT COUNT(cid) FROM Course)); -- 嵌套,效率相对低
 
SELECT s.sid, s.sname FROM student s, sc WHERE s.sid = sc.sid GROUP BY sc.sid HAVING COUNT(sc.sid) < (SELECT COUNT(cid) FROM Course);

-- 11、查询至少有一门课与学号为“08”的同学所学相同的同学的学号和姓名;
SELECT DISTINCT(s.sid), s.sname FROM student s, sc WHERE s.sid = sc.sid AND cid IN(SELECT cid FROM sc WHERE sid = 08); -- 嵌套

-- 12、查询至少学过学号为“01”同学所有一门课的其他同学学号和姓名;
SELECT DISTINCT(s.sid), s.sname FROM student s, sc WHERE s.sid = sc.sid AND s.sid <> 08 AND cid IN(SELECT cid FROM sc WHERE sid = 08);

-- 13、把“SC”表中“王五”老师教的课的成绩都更改为此课程的平均成绩;--------xxx
UPDATE SC SET score = (
SELECT a.avgs FROM (
SELECT AVG(score) avgs FROM Course c, Teacher t,SC 
WHERE c.cid = sc.cid AND c.tid = t.tid AND t.tname = '王五') a )
WHERE sc.cid =(
SELECT b.cid FROM (
SELECT DISTINCT c.cid 
FROM Course c, Teacher t,SC 
WHERE c.cid = sc.cid AND c.tid = t.tid AND t.tname = '王五') b );



SELECT * FROM sc s
LEFT JOIN course c ON s.cid=c.cid
LEFT JOIN teacher t ON t.tid=c.tid
WHERE t.tname='王五';

SELECT s.sid,AVG(s.score) AVG,t.tname FROM sc s
LEFT JOIN course c ON s.cid=c.cid
LEFT JOIN teacher t ON t.tid=c.tid
WHERE t.tname='王五' GROUP BY c.cid;

UPDATE sc SET score=(
SELECT a.avg FROM (
SELECT AVG(s.score) AVG FROM sc s
LEFT JOIN course c ON s.cid=c.cid
LEFT JOIN teacher t ON t.tid=c.tid
WHERE t.tname='王五' GROUP BY c.cid
) a
)
WHERE sid IN (
SELECT b.sid FROM (
SELECT s.sid FROM sc s
LEFT JOIN course c ON s.cid=c.cid
LEFT JOIN teacher t ON t.tid=c.tid
WHERE t.tname='王五'
)b
);


-- 14、查询和“02”号的同学学习的课程完全相同的其他同学学号和姓名;    -- 重点记一下
SELECT s.sid, s.sname FROM student s, sc WHERE s.sid = sc.sid AND sc.cid IN (SELECT cid FROM sc WHERE sid = 02) GROUP BY sc.sid HAVING COUNT(sc.sid) = (SELECT COUNT(sid) FROM sc WHERE sid = 02);

-- 15、删除学习“王五”老师课的SC表记录;
DELETE FROM sc WHERE cid = (SELECT cid FROM course c, teacher t WHERE c.tid = t.tid AND tname = '王五');

-- 16、向SC表中插入一些记录,这些记录要求符合以下条件:没有上过编号03课程的同学学号、02号课的平均成绩;-----回过头来弄懂!
INSERT INTO sc SET sid = (SELECT DISTINCT(sid) FROM sc WHERE cid <> 03), cid = 03, score = (SELECT AVG(score) FROM sc WHERE sid = 02));

INSERT SC SELECT Sid, 02,(SELECT AVG(score) FROM SC WHERE Cid=02) FROM Student WHERE Sid NOT IN (SELECT Sid FROM SC WHERE Cid=02); 

-- 17、按平均成绩从高到低显示所有学生的“数学”、“英语”、“语文”三门的课程成绩,按如下形式显示:学生ID,数学,英语,语文,有效课程数,有效平均分 ------
SELECT Sid AS 学生ID 
,(SELECT score FROM SC WHERE SC.Sid=t.Sid AND Cid=02) AS 数学 
,(SELECT score FROM SC WHERE SC.Sid=t.Sid AND Cid=03) AS 英语 
,(SELECT score FROM SC WHERE SC.Sid=t.Sid AND Cid=01) AS 语文 
,COUNT(*) AS 有效课程数, AVG(t.score) AS 平均成绩 
FROM SC AS t 
GROUP BY Sid
ORDER BY AVG(t.score);

-- 18、查询各科成绩最高和最低的分:以如下形式显示:课程ID,最高分,最低分
SELECT DISTINCT l.cid AS 课程ID, h.score AS 最高分, l.score AS 最低分 
FROM sc AS h ,sc AS l 
WHERE h.cid = l.cid 
AND h.score =(SELECT MAX(score) FROM sc WHERE cid = l.cid) 
AND l.score = (SELECT MIN(score) FROM sc WHERE cid = l.cid);

-- 19、按各科平均成绩从低到高和及格率的百分数从高到低顺序查询 -- 100 * SUM(CASE WHEN ISNULL(score,0)>=60 THEN 1 ELSE 0 END)/COUNT(*) AS 及格百分数
SELECT cid AS 课程号, AVG(score) AS 平均成绩, 100 * SUM(CASE WHEN score >=60 THEN 1 ELSE 0 END)/COUNT(*) AS 及格百分数 FROM sc GROUP BY cid ORDER BY (100 * SUM(CASE WHEN score>=60 THEN 1 ELSE 0 END)/COUNT(*)) DESC;

-- 20、查询如下课程平均成绩和及格率的百分数(用"1行"显示): 语文,英语
SELECT cid AS 课程号, AVG(score) AS 平均成绩, 100 * SUM(CASE WHEN score >=60 THEN 1 ELSE 0 END)/COUNT(*) AS 及格百分数 FROM sc WHERE cid = 01 OR cid = 03 GROUP BY cid;

-- 21、查询不同老师所教不同课程平均分从高到低显示
SELECT tname 老师姓名, cname 课程名, AVG(score) 平均成绩 FROM teacher t, course c, sc WHERE t.tid = c.tid AND c.cid = sc.cid GROUP BY t.tid ORDER BY AVG(score) DESC;

-- 22、查询如下课程成绩第3名到第6名的学生成绩单:语文(01),英语(03) 格式如下:[学生ID], [学生姓名], 语文, 英语, 平均成绩
SELECT s.sid, s.sname,IFNULL(cn.score,0) 语文, IFNULL(en.score,0) 英语, (IFNULL(cn.score,0)+IFNULL(en.score,0))/2 平均分 
FROM student s 
LEFT JOIN sc cn ON cn.sid = s.sid AND cn.cid = 01 
LEFT JOIN sc en ON en.sid = s.sid AND en.cid = 03 
ORDER BY 平均分 DESC LIMIT 3,3;

-- 23、统计列印各科成绩,各分数段人数:课程ID,课程名称,[100-85],[85-70],[70-60],[ <60]
SELECT c.cid, c.cname, 
SUM(CASE WHEN score BETWEEN 85 AND 100 THEN 1 ELSE 0 END) AS 优秀,
SUM(CASE WHEN score BETWEEN 75 AND 85 THEN 1 ELSE 0 END) AS 良好,
SUM(CASE WHEN score BETWEEN 60 AND 75 THEN 1 ELSE 0 END) AS 及格,
SUM(CASE WHEN score < 60 THEN 1 ELSE 0 END) AS 不及格
FROM course c, sc 
WHERE c.cid = sc.cid
GROUP BY sc.cid;

SELECT c.cid AS 课程ID, c.cname AS 课程名称, 
SUM(CASE WHEN score BETWEEN 85 AND 100 THEN 1 ELSE 0 END) AS 优秀, 
SUM(CASE WHEN score BETWEEN 75 AND 85 THEN 1 ELSE 0 END) AS 良好, 
SUM(CASE WHEN score BETWEEN 60 AND 75 THEN 1 ELSE 0 END) AS 及格,
SUM(CASE WHEN score < 60 THEN 1 ELSE 0 END) 不及格 
FROM course c, sc 
WHERE c.cid = sc.cid
GROUP BY c.cid;

-- 24、查询学生平均成绩及其名次
SELECT sid 学号, AVG(score) 平均成绩 FROM sc GROUP BY sid ORDER BY AVG(score) DESC;

SELECT 1+(SELECT COUNT( DISTINCT 平均成绩)
FROM (SELECT sid,AVG(score) 平均成绩
FROM SC
GROUP BY sid
) t1
WHERE 平均成绩 > t2.平均成绩) 名次,
sid AS 学生学号, 平均成绩
FROM (SELECT sid,AVG(score) 平均成绩
FROM sc
GROUP BY sid
) t2
ORDER BY 平均成绩 DESC;


SELECT 1+(SELECT COUNT( DISTINCT 平均成绩) 
FROM (SELECT Sid,AVG(score) AS 平均成绩 
FROM SC 
GROUP BY Sid 
) AS T1 
WHERE 平均成绩 > T2.平均成绩) AS 名次, 
Sid AS 学生学号,平均成绩 
FROM (SELECT Sid,AVG(score) 平均成绩 
FROM SC 
GROUP BY Sid 
) AS T2 
ORDER BY 平均成绩 DESC; 


-- 25、查询各科成绩前三名的记录:(不考虑成绩并列情况) --------------xxxxx
SELECT cid 课程ID, score 成绩 FROM sc ORDER BY cid LIMIT 0,3;

SELECT sid 学号, cid 课程ID, score 成绩 FROM sc WHERE cid = 1 ORDER BY score DESC LIMIT 0,3;
SELECT sid 学号, cid 课程ID, score 成绩 FROM sc WHERE cid = 2 ORDER BY score DESC LIMIT 0,3;
SELECT sid 学号, cid 课程ID, score 成绩 FROM sc WHERE cid = 3 ORDER BY score DESC LIMIT 0,3;

-- 26、查询每门课程被选修的学生数
SELECT cid, COUNT(sid) FROM sc GROUP BY cid;

-- 27、查询出只选修了两门课程的全部学生的学号和姓名
SELECT s.sid, s.sname FROM student s, sc WHERE s.sid = sc.sid GROUP BY sc.sid HAVING COUNT(sc.sid) = 2;

-- 28、查询男生、女生人数
SELECT COUNT(sid) 男生人数 FROM student WHERE ssex = '男';
SELECT COUNT(sid) 女生人数 FROM student WHERE ssex = '女';

-- 29、查询姓“王”的学生名单
SELECT * FROM student WHERE sname LIKE '王%';

-- 30、查询同名同性学生名单,并统计同名人数
SELECT sname 姓名, COUNT(*) 人数 FROM student GROUP BY sname,ssex HAVING COUNT(*) >= 2;

-- 31、1981年出生的学生名单(注:Student表中Sage列的类型是DATETIME) 
原题目答案:
SELECT Sname, CONVERT(CHAR (11),DATEPART(YEAR,Sage)) AS age 
FROM student 
WHERE  CONVERT(CHAR(11),DATEPART(YEAR,Sage))='1981'; 

-- 改成19岁的人的名单
SELECT sname FROM student WHERE sage = 19;

-- 32、查询每门课程的平均成绩,结果按平均成绩升序排列,平均成绩相同时,按课程号降序排列
SELECT cid 课程号, AVG(score) 平均成绩 FROM sc GROUP BY cid ORDER BY AVG(score), cid DESC;

-- 33、查询平均成绩大于75的所有学生的学号、姓名和平均成绩
SELECT s.sid, sname, AVG(score) FROM student s, sc WHERE s.sid = sc.sid GROUP BY s.sid HAVING AVG(score) > 75;

-- 34、查询课程名称为“数学”,且分数低于60的学生姓名和分数
SELECT sname, score FROM student s, course c, sc WHERE s.sid = sc.sid AND c.cid = sc.cid AND cname='数学' AND score < 60;

-- 35、查询所有学生的选课情况;
SELECT s.sid, sc.cid, s.sname, c.cname FROM student s, course c, sc WHERE s.sid = sc.sid AND c.cid = sc.cid;

-- 36、查询任何一门课程成绩在70分以上的姓名、课程名称和分数;
SELECT s.sname, c.cname, score FROM student s, course c ,sc WHERE s.sid = sc.sid AND c.cid = sc.cid AND score > 70;

-- 37、查询不及格的课程,并按课程号从大到小排列
SELECT s.sname, c.cid, c.cname, score FROM student s, course c, sc WHERE s.sid = sc.sid AND c.cid = sc.cid AND score < 60 ORDER BY cid DESC;

-- 38、查询课程编号为02且课程成绩在80分以上的学生的学号和姓名;
SELECT s.sid, s.sname FROM student s, sc WHERE s.sid = sc.sid AND score > 80 AND sc.cid=02;

-- 39、求选了课程的学生人数
SELECT COUNT(a.s) 选了课程的人数 FROM (SELECT COUNT(sid) s FROM sc GROUP BY sid) a;	-- 去除了重复的学生

SELECT COUNT(*) FROM sc;	-- 不去除重复学生

-- 40、查询选修“叶平”老师所授课程的学生中,成绩最高的学生姓名及其成绩
SELECT sname, MAX(score) FROM student s, course c, teacher t, sc WHERE s.sid = sc.sid AND c.cid = sc.cid AND c.tid = t.tid AND tname = '张三';

-- 41、查询各个课程及相应的选修人数
SELECT cid, COUNT(*) FROM sc GROUP BY cid;

-- 42、查询不同课程成绩相同的学生的学号、课程号、学生成绩
SELECT sid, cid, score FROM sc WHERE score IN (SELECT score FROM sc GROUP BY score HAVING COUNT(score) >= 2) ORDER BY score;  -- 所有人之间对比

SELECT DISTINCT A.Sid,B.score FROM SC A ,SC B WHERE A.Score=B.Score AND A.Cid <>B.Cid ;  -- 单人成绩对比

-- 43、查询每门课程成绩最好的前两名
SELECT sid 学号, cid 课程ID, score 成绩 FROM sc WHERE cid = 1 ORDER BY score DESC LIMIT 0,2;
SELECT sid 学号, cid 课程ID, score 成绩 FROM sc WHERE cid = 2 ORDER BY score DESC LIMIT 0,2;
SELECT sid 学号, cid 课程ID, score 成绩 FROM sc WHERE cid = 3 ORDER BY score DESC LIMIT 0,2;

-- 44、统计每门课程的学生选修人数(超过7人的课程才统计)。要求输出课程号和选修人数,查询结果按人数降序排列,若人数相同,按课程号升序排列
SELECT cid 课程ID, COUNT(*) 人数 FROM sc GROUP BY cid HAVING COUNT(*) >7 ORDER BY 人数, 课程ID DESC;

-- 45、检索至少选修两门课程的学生学号
SELECT sid FROM sc GROUP BY sid HAVING COUNT(sid) >=2;

-- 46、查询全部学生都选修的课程的课程号和课程名
SELECT c.cid, c.cname,COUNT(sc.sid) FROM course c, sc WHERE c.cid = sc.cid GROUP BY c.cid HAVING COUNT(sc.sid) = (SELECT COUNT(*) FROM student);

-- 47、查询没学过“王五”老师讲授的任一门课程的学生姓名
SELECT s1.sname FROM student s1 WHERE s1.sname NOT IN(
SELECT s.sname FROM student s, course c, teacher t, sc WHERE s.sid = sc.sid AND c.cid = sc.cid AND c.tid = t.tid AND t.tname = '王五');

-- 48、查询两门以上不及格课程的同学的学号及其平均成绩
SELECT sid, AVG(score) FROM sc WHERE sid IN (SELECT sid FROM sc WHERE score < 60 GROUP BY sid HAVING COUNT(*)>=2);

-- 49、检索“01”课程分数小于60,按分数降序排列的同学学号
SELECT sid, score FROM sc WHERE cid = 01 AND score < 60 ORDER BY score DESC;

-- 50、删除“02”同学的“01”课程的成绩
DELETE FROM sc WHERE sid = 02 AND cid = 01;


-- 以上答案存在些许错误,仅供参考。

答案存在些许错误,仅供参考。

参考文章:https://blog.csdn.net/xuebing1995/article/details/74614896?tdsourcetag=s_pctim_aiomsg(如有侵权,联系删除)

本文链接:https://blog.csdn.net/oneeyear/article/details/82890186

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值