mysql操作练习

数据库表结构,数据库具体表结构及表中数据:点击获取sql文件

department(dNo,dName,officeRoom,homepage)
student(sNo,sName,sex,age,dNo)
course(cNo,cName,cPNo,credit,dNo)
sc(sNo,cNo,score,recordDate)
问题及解决方案:

Query
一、单表
(1)查询所有年龄大于等于20岁的学生学号、姓名;
	SELECT sNO,sName FROM student WHERE age>=20;
(2)查询所有姓钱的男生学号、姓名、出生年份;
	SELECT sNo,sName,2017-age FROM student WHERE sName LIKE '钱%';
(3)查询所有学分大于3的课程名称;
	SELECT cName FROM course WHERE credit>3;
(4)查询所有没有被分配到任何学院的学生姓名;
	SELECT sName FROM student WHERE dNo IS NULL OR dNo='';
(5)查询所有尚未设置主页的学院名称。
	SELECT dName FROM department WHERE homePage IS NULL OR homePage ='';
二、聚集
(1)查询各个学院的平均年龄;
	SELECT department.dName,student.dNo,AVG(student.age) FROM department,student WHERE 	student.dNo=department.dNo GROUP BY student.dNo;
(2)查询每个学生选修课程的平均分;
	SELECT sName,student.sNo,AVG(score) FROM student,sc WHERE student.sNo=sc.sNo GROUP 	BY sc.sNo;
(3)查询各课程的平均分;
	SELECT	course.cNo,cName,AVG(score) FROM course,sc WHERE course.cNo=sc.cNo GROUP BY 	course.cNo;
(4)查询各学院开设的课程门数;
	SELECT course.dNo,dName,COUNT(*) FROM department,course WHERE course.dNo=department.dNo GROUP BY dNo;
(5)查询各门课程选修人数。
	SELECT cName,course.cNo 课程编号,COUNT(*) AS 选修人数 FROM course,sc WHERE sc.cNo=course.cNo GROUP BY course.cNo;


三、多表
(1)查询“信息学院”所有学生学号与姓名;
SELECT student.sNo, student.sName FROM student,department WHERE student.dNo=department.dNo AND department.dName='信息学院';
(2)查询“软件学院”开设的所有课程号与课程名称;
SELECT course.cNo,course.cName FROM course,department WHERE course.dNo=department.dNo AND department.dName='软件学院';
(3)查询与“陈丽”在同一个系的所有学生学号与姓名;
 SELECT student.sNo,student.sName FROM student WHERE student.dNo  = (SELECT student.dNo FROM student,department WHERE student.dNo=department.dNo AND student.sName = '陈丽');
(4)查询与“张三”同岁的所有学生学号与姓名;
SELECT student.sNo,student.sName FROM student WHERE student.age IN (SELECT age FROM student WHERE sname='张三');
(5)查询与“张三”同岁且不与“张三”在同一个系的学生学号与姓名;
	SELECT student.sNo,student.sName FROM student WHERE student.age IN (SELECT age FROM student WHERE sname='张三') AND student.dNo NOT IN (SELECT dNo FROM student WHERE sName='张三');
(6)查询学分大于“离散数学”的所有课程名称;
SELECT cName FROM course WHERE credit > (SELECT credit FROM course WHERE cName ='离散数学');
(7)查询选修了课程名为“组合数学”的学生人数;
	SELECT COUNT(*) FROM sc WHERE cNo IN (SELECT cNo FROM course WHERE cName='离散数学');
(8)查询没有选修“离散数学”的学生姓名;
SELECT COUNT(*) FROM student WHERE sNo NOT IN (SELECT sNo FROM sc WHERE cNo IN (SELECT cNo FROM course WHERE cName='离散数学'));
(9)查询与“算法设计与分析”、“移动计算”学分不同的所有课程名称;
SELECT course.cName FROM course WHERE credit NOT IN(SELECT credit FROM course WHERE cName ='算法设计与分析' OR cName='移动计算');
(10)查询平均分大于等于90分的所有课程名称;
SELECT course.cName FROM sc,course WHERE course.cNo=sc.cNo GROUP BY course.cNo HAVING AVG(sc.score)>=90;
(11)查询选修了“离散数学”课程的所有学生姓名与成绩;
SELECT student.sName,sc.score FROM student,sc WHERE sc.sNo=student.sNo AND sc.cNo IN (SELECT cNo FROM course WHERE course.cName='离散数学');
(12)查询“王兵”所选修的所有课程名称及成绩;
SELECT sc.score ,course.cName   FROM sc,course WHERE  sc.cNo=course.cNo AND sc.sNo IN (SELECT sNo FROM student WHERE student.sName='王兵');
(13)查询所有具有不及格课程的学生姓名、课程名与成绩;
SELECT student.sName,course.cName,sc.score FROM student,course,sc WHERE student.sNo=sc.sNo AND course.cNo=sc.cNo AND sc.score<60;
(14)查询选修了“文学院”开设课程的所有学生姓名;
SELECT student.sName FROM student WHERE student.sNo IN (SELECT sc.sNo FROM sc WHERE sc.cNo IN (SELECT cNo FROM course WHERE course.dNo IN(SELECT dNo FROM department WHERE department.dName='文学院')));
(15)查询“信息学院”所有学生姓名及其所选的“信息学院”开设的课程名称。
SELECT student.sName,course.cName  FROM student,course,sc WHERE  student.sNo=sc.sNo AND course.cNo=sc.cNo AND course.dNo IN(SELECT department.dNo FROM department WHERE department.dName='信息学院') AND student.dNo = (SELECT dNo FROM department WHERE department.dName='信息学院');
四、综合
(1)查询所有学生及其选课信息(包括没有选课的学生);
SELECT student.sName,(SELECT course.cName FROM course WHERE course.cNo=sc.cNo) FROM student  LEFT JOIN sc ON student.sNo=sc.sNo;
(2)查询“形式语言与自动机”先修课的课程名称;
SELECT course.cName FROM course WHERE course.cNo IN (SELECT course.cPNo FROM course WHERE course.cName = '形式语言与自动机');
(3)查询“形式语言与自动机”间接先修课课程名称;
SELECT course.cName FROM course WHERE course.cNo IN(SELECT course.cPNo FROM course WHERE course.cNo IN(SELECT course.cPNo FROM course WHERE course.cName='形式语言与自动机'));
(4)查询先修课为组合数学的课程名称;
SELECT course.cName FROM course WHERE course.cPNo IN (SELECT course.cNo FROM course WHERE course.cName ='组合数学');
(5)查询所有没有先修课的课程名称;
SELECT course.cName FROM course WHERE course.cPNo IS NULL;
(6)查询所有没选修组合数学课程的学生姓名;
SELECT student.sName FROM student WHERE student.sNo NOT IN (SELECT sc.sNo FROM sc WHERE sc.cNo IN (SELECT course.cNo FROM course WHERE course.cName='离散数学'));
(7)查询所有选修了组合数学但没选修其先修课的学生姓名;
SELECT student.sName FROM student WHERE student.sNo NOT IN (SELECT sc.sNo FROM sc WHERE sc.cNo IN (SELECT course.cPNo FROM course WHERE course.cName='离散数学')) AND student.sNo IN (SELECT sc.sNo FROM sc WHERE sc.cNo IN(SELECT course.cNo FROM course WHERE course.cName='离散数学'));
(8)查询选修课程总学分大于等于8的学生姓名;
SELECT student.sName FROM student WHERE student.sNo IN(SELECT  sc.sNo FROM sc,course WHERE course.cNo=sc.cNo GROUP BY sc.sNo HAVING (SUM(course.credit)>=8));
(9)查询选修了3门以上课程且成绩都大于85分的学生学号与姓名;
 SELECT student.sName ,student.sNo FROM student WHERE  student.sNo IN(SELECT DISTINCT sc.sNo  FROM sc WHERE sc.sNo IN( SELECT sc.sNo FROM sc GROUP BY sc.sNo
 HAVING (COUNT(*)>3) ) AND sc.sNo NOT IN(SELECT sc.sNo FROM sc WHERE sc.score<=85));
(10)查询恰好选修了3门课并且都及格的学生姓名;
SELECT student.sName FROM student WHERE student.sNo 
IN( SELECT sc.sNo FROM sc GROUP BY sc.sNo HAVING (COUNT(*)=3)) AND student.sNo NOT IN(SELECT DISTINCT sc.sNo FROM sc WHERE sc.score<60);  
(11)查询人数多于10的学院名称;
SELECT department.dName FROM department WHERE department.dNo IN(SELECT DISTINCT student.dNo FROM student GROUP BY student.dNo HAVING (COUNT(*)>10));

(12)查询平均成绩高于张三的学生姓名;
SELECT sc.sNo FROM sc GROUP BY sc.sNo 
HAVING (AVG(sc.score)> ALL(SELECT AVG(score) FROM sc WHERE sc.sNo =(SELECT sno FROM student WHERE student.sName='宁灿') ) );

(13)查询所有选修了离散数学并且选修了组合数学课程的学生姓名;
SELECT  DISTINCT sc.sNo FROM sc WHERE sc.sNo IN(SELECT sc.sNo FROM sc 
WHERE sc.cNo IN (SELECT course.cNo FROM course WHERE course.cName ='离散数学'))
 AND sc.sNo IN (SELECT sc.sNo FROM sc WHERE sc.cNo IN (SELECT course.cNo FROM course WHERE course.cName ='编译原理'));

(14)查询软件学院离散数学课程平均分;
SELECT AVG(sc.score) FROM sc 
WHERE sc.cNo IN (SELECT course.cNo FROM course WHERE course.cName ='离散数学') 
AND sc.sNo IN(SELECT student.sNo FROM student WHERE student.dNo IN (SELECT department.dNo FROM department WHERE department.dName='软件学院'));

(15)查询平均学分积小于70分的学生姓名。
SELECT DISTINCT sc.sNo FROM sc,course WHERE course.cNo=sc.cNo GROUP BY sc.sNo HAVING(SUM(course.credit *sc.score)/SUM(course.credit)<70);(错误的,因为少考虑一种情况,选课了,但成绩为null,你不能把这一科的成绩放入学分绩的计算中)

select sname
from student
where sno in(select sc.sno
             from sc,course
             where sc.cno=course.cno and score is not null and credit is not null
             group by sno
             having SUM(score*credit)/SUM(credit)<70);


(16)查询选修了“信息学院”开设全部课程的学生姓名。
SELECT sc.sNo FROM sc WHERE sc.cNo IN(SELECT DISTINCT course.cNo FROM course WHERE course.dNo IN (SELECT department.dNo FROM department WHERE department.dName='信息学院')) GROUP BY sc.sNo HAVING COUNT(*) = (SELECT COUNT(course.cNo) FROM course WHERE course.dNo IN (SELECT department.dNo FROM department WHERE department.dName='信息学院'));


SELECT sno,sName 
FROM student s
WHERE NOT EXISTS(SELECT * 
                 FROM course c
                 WHERE c.dno = (select dno from department where dname='信息学院')
                 AND NOT EXISTS(SELECT * 
                                FROM sc
                                WHERE sc.sno=s.sno AND sc.cno=c.cno));
(17)查询选修了“杨佳伟”同学所选修的全部课程的学生姓名。
SELECT student.sName FROM student WHERE student.sNo IN(SELECT sc.sNo FROM sc WHERE sc.cNo IN(SELECT sc.cNo FROM sc WHERE sc.sNo IN(SELECT student.sNo FROM student WHERE student.sName='杨佳伟')) GROUP BY sc.sNo HAVING(COUNT(*)>=(SELECT COUNT(sc.cNo) FROM sc WHERE sc.sNo IN(SELECT student.sNo FROM student WHERE student.sName='杨佳伟'))));


select sname
from student s
where not exists(select *
                 from sc sc2                 
                 where sc2.sno=(select sno from student where sname='杨佳伟')
                 and not exists(select *
                                from sc sc3
                                where s.sno=sc3.sno and sc2.cno=sc3.cno))
  and s.sname<>'杨佳伟';

外加一些补充的题

(2)查询“形式语言与自动机”先修课的课程名称;
select c2.cName
from course c1,course c2
where c1.cPNo=c2.cNo
  and c1.cName='形式语言与自动机';
(3)查询“形式语言与自动机”间接先修课课程名称;
select c3.cName
from course c1,course c2,course c3
where c1.cPNo=c2.cNo and c2.cPNo=c3.cNo
  and c1.cName='形式语言与自动机';
(4)查询先修课为编译原理数学的课程名称;
(5)查询间接先修课为离散数学的课程名称;
(6)查询所有没有先修课的课程名称;
(7)查询所有没选修“形式语言与自动机”课程的学生姓名;
(8)查询所有选修了“形式语言与自动机”但没选修其先修课的学生姓名;
(9)查询选修课程总学分大于等于28的学生姓名及其选修课程总学分;
select s.sNo,s.sName,v.sumCredit
from student s, (select sNo,SUM(credit)
                 from sc, course c
                 where sc.cNo=c.cNo
                 group by sc.sNo
                 having SUM(credit)>=28) as v(sNo,sumCredit)
where s.sNo=v.sNo;
--最佳实践 当要查询某个特殊的属性(这个属性只在某一张表中出现),则from 后出现此表,并且用一个子查询来定位此表所需数据的主键

(10)查询选修了3门以上课程且成绩都大于85分的学生学号与姓名;
(11)查询恰好选修了3门课并且都及格的学生姓名;
(12)查询人数多于6的学院名称及其学生人数;
select d.dName,v.countOf
from department d, (select dNo,count(sNo)
                    from student s
                    group by dNo
                    having count(sNo)>6) as v(dNo,countOf)
where d.dNo=v.dNo;
(13)查询平均成绩高于王兵的学生姓名;
(14)查询所有选修了离散数学并且选修了编译原理课程的学生姓名;
(15)查询软件学院离散数学课程平均分;

(16)查询年龄与“软件学院”所有学生年龄都不相同学生姓名及其年龄和学院;
select s.sNo,s.sName,s.age,d.dName
from student s left join department d on s.dNo=d.dNo
where age NOT IN (select age
                  from student
                  where age is not null
                    and dNo = (select dNo
                               from department
                               where dName='软件学院'));
--注意使用in,not in,=,<> 时,根据需求,若是null不满足要求,则左边和右边都不能为空
比如:错误案例
SELECT student.sName,student.dNo,student.age  FROM student WHERE student.age IS NOT NULL AND student.age NOT IN
	(SELECT DISTINCT(student.age) FROM student 
		WHERE student.dNo=(SELECT dno FROM department WHERE department.dName='软件学院'));  
正确案例
SELECT student.sName,student.dNo,student.age  FROM student WHERE student.age IS NOT NULL AND student.age NOT IN
	(SELECT DISTINCT(student.age) FROM student 
		WHERE  student.age IS NOT NULL AND student.dNo=(SELECT dno FROM department WHERE department.dName='软件学院'));



(17)查询各学院选修同一门课人数大于4的学院、课程及选课人数;
select d.dName,c.cName,v.countOf
from course c,department d, (select dNo,cNo,count(s.sNo)
                              from student s, sc
                              where s.sNo=sc.sno
                              group by dNo,cNo
                              having count(sc.sNo)>4) as v(dNo,cNo,countOf)
 where c.cNo=v.cNo and d.dNo=v.dNo;
(18)查询仅仅选修了“高等数学”一门课程的学生姓名;(学号、姓名及所在学院名称)
select sc.sNo,s.sName
from sc,student s
where sc.sNo=s.sNo
  and sc.sNo NOT IN (select sNo
                     from sc
                     where cNo <> (select cNo
                                   from course
                                   where cName='高等数学'));
select sc.sNo,s.sName,d.dName
from sc, student s, department d
where sc.sNo=s.sNo and s.dNo=d.dNo
  and sc.sNo NOT IN (select sNo
                  from sc
                  where cNo <> (select cNo
                                from course
                                where cName='高等数学'));(丢失一名没有学院的学生170105,连接空值导致)
正确写法如下:
select sc.sNo,s.sName,d.dName
from sc natural join student s left join department d on s.dNo=d.dNo
where sc.sNo NOT IN (select sNo
                     from sc
                     where cNo <> (select cNo
                                   from course
                                   where cName='高等数学'));

(19)查询平均学分积小于70分的学生姓名。
select sname
from student
where sno in(select sc.sno
             from sc,course
             where sc.cno=course.cno and score is not null and credit is not null
             group by sno
             having SUM(score*credit)/SUM(credit)<70);
--逻辑思维的严密性,要考虑到或许有的成绩没有出来,结果为null,这一条记录不应被考虑进去
--错误
SELECT student.sName,sub.sumcre FROM student,
	(SELECT sc.sNo AS ssno,SUM(sc.score * course.credit)/SUM(course.credit) AS sumcre FROM sc,course WHERE course.cNo=sc.cNo GROUP BY sc.sNo HAVING sumcre<70) AS sub 
	WHERE sub.ssno=student.sNo;
--正确
 SELECT student.sName,sub.sumcre FROM student,
	(SELECT sc.sNo AS ssno,SUM(sc.score * course.credit)/SUM(course.credit) AS sumcre FROM sc,course WHERE course.cNo=sc.cNo AND sc.score IS NOT NULL GROUP BY sc.sNo HAVING sumcre<70) AS sub 
	WHERE sub.ssno=student.sNo; 



(20)查询选修了“信息学院”开设全部课程的学生姓名。
SELECT sno,sName 
FROM student s
WHERE NOT EXISTS(SELECT * 
                 FROM course c
                 WHERE c.dno = (select dno from department where dname='信息学院')
                 AND NOT EXISTS(SELECT * 
                                FROM sc
                                WHERE sc.sno=s.sno AND sc.cno=c.cno));
--exists写法有一点需要注意: exists子句中不可以使用本语句的父语句的select参数,因为这里首先执行的是exists字句,不然会报错误,比如下面
SELECT student.sNo  FROM student WHERE
	NOT EXISTS( SELECT course.cNo AS ccno FROM course 
	WHERE NOT EXISTS(SELECT sc.cNo FROM sc WHERE sc.sNo=student.sNo AND sc.cNo=ccno )
	 AND course.dNo=(SELECT department.dNo FROM department WHERE department.dName='信息学院') );
正确写法:
SELECT student.sNo  FROM student WHERE
	NOT EXISTS( SELECT course.cNo FROM course 
	WHERE NOT EXISTS(SELECT sc.cNo FROM sc WHERE sc.sNo=student.sNo AND sc.cNo=course.cNo )
	 AND course.dNo=(SELECT department.dNo FROM department WHERE department.dName='信息学院') ); 

(21)查询选修了“杨佳伟”同学所选修的全部课程的学生姓名。
select sname
from student s
where not exists(select *
                 from sc sc2                 
                 where sc2.sno=(select sno from student where sname='杨佳伟')
                 and not exists(select *
                                from sc sc3
                                where s.sno=sc3.sno and sc2.cno=sc3.cno))
  and s.sname<>'杨佳伟';
选出这样的学生,没有一科杨佳伟选了,而这个同学没选
查询过程:找出所有学生,不存在一科满足杨佳伟选了,而这个同学没选,他才会被选中。
sc2表中所有选课数据都是杨佳伟的,所以遍历整个sc2表,若是发现一条记录这个学生没选,则这个学生不被打印,第二个not exists表示这一条记录,若是这个学生没有选择
,则not exists返回true,这条记录被提交给第一个not exists则这个学生不能被打印。


聚集函数 group by ,被分组的属性值是相同的,合并在一起,不可以直接调本组中其它属性的值。

SELECT sno,AVG(age) FROM student;  显示便没有意义。因为avg已经把student表分为一组,不可以再调用sno属性。


建议不要使用 ANY/SOME 或 ALL ,容易误解,可以结合MIN,MAX来代替。x>ALL(score)改为   x>MAX(score) ; x>ANY(score) 改为 x>MIN(score)  


关于exists和not exists用法:

例1:查询所有选修了1号课程的学生的姓名。
解法1:利用exists
首先取Student表中的一个元组,然后在SC表中依次找SC.Sno=该元组的Sno,并且对应的Cno='1',如果存在,则外层查询的where子句返回为真,则Student表中的该元组可以输出。然后依次遍历Student表中的其他元组。
举个例子:对于在学生表中学号等于2002151121这个元组,在SC表中第一条记录即符合条件,然后where 子句返回 true,所以该条元组可以输出。然后依次遍历。
select Sname
from  Student
where exists
(
select *
from SC
where Sno = Student.Sno AND Cno='1'
);
解法2:利用连接查询
select Sname
from Student,SC
where Student.Sno=SC.Sno AND SC.Cno='1';
例2:查询没有选修1号课程的学生的姓名。
解:
select Sname
from Student
where not exists
(
select *
from SC
where Sno=Student.Sno  AND   Cno='1'
);
例3:查询选修了全部课程的学生姓名。
select Sname
from Student
where not exists
(
select *
from Course
where not exists
(
select *
from  SC
where Sno=Student.Sno AND
Cno=Course.Cno
) );
查找语义:查询这样的学生,没有一门课程是他不选修的。
查找过程:
首先,选取Student表中的一个元组,然后在依次判断Course表中的每个元组是否可以输出,只要有一个课程可以输出,则最外层查询的where子句返回为false;而在判断某个课程是否可以输出时,则要利用第三层查询,利用当前的学号和当前的课程号,在SC表中查询,如果存在,则第二层查询where子句返回false。至此,每一门课程都不可以输出时,这个学号对应的元组才可以输出。表示这个学生选修了全部的课程。
例4:至少选修了学生200215122选修的全部课程的学生号码。
select distinct Sno
from SC SCX
where not exists
(
select *
from SC SCY
where SCY.Sno='2002151122'  AND
not exists
(
select *
from SC SCZ
where SCZ.Sno=SCX.Sno  AND
SCZ.Cno=SCY.Cno));
查询语义:不存在这样的课程y,学生200215122选修了y,而学生x没选。
查询过程:先在SCX表中选一条记录,比方说第一条,然后再看SCY表中,只有SCY表中全部不能输出,第一层查询的where子句才返回true,第一条记录就可以输出;所以就要一次查看SCY表中的每一个元组,前三个,因为学号首先不满足=200215122所以必然不能输出,第四个的话,就要看其AND后面的not exists返回什么值,而这又取决于第三层查询中是否存在满足学号等于SCX.Sno且课程号=SCY.Cno的元组,经查看,有 ,则返回false,所以第四个也不能输出,第五个类似,所以,第一层查询的not exists返回true。所以第一条记录可以输出。


  • 5
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值