SQL练习之基础篇

  有感于SQL的一些问题和细节一直困扰着我,因此找来相关的练习来对一些知识进行巩固和加深。得意

  文章的习题参考于他人的一个博客,链接如下 SQL基础练习

  建表具体数据如下:

# 创建数据库STUDENT
CREATE DATABASE STUDENT;
# 创建表STUDENT
CREATE TABLE STUDENT
(SNO VARCHAR(3) NOT NULL, 
SNAME VARCHAR(4) NOT NULL,
SSEX VARCHAR(2) NOT NULL, 
SBIRTHDAY DATETIME,
CLASS VARCHAR(5));
# 创建表COURSE
CREATE TABLE COURSE
(CNO VARCHAR(5) NOT NULL, 
CNAME VARCHAR(10) NOT NULL, 
TNO VARCHAR(10) NOT NULL);
# 创建表SCORE 
CREATE TABLE SCORE 
(SNO VARCHAR(3) NOT NULL, 
CNO VARCHAR(5) NOT NULL, 
DEGREE NUMERIC(10, 1) NOT NULL);
# 创建表TEACHER
CREATE TABLE TEACHER 
(TNO VARCHAR(3) NOT NULL, 
TNAME VARCHAR(4) NOT NULL, TSEX VARCHAR(2) NOT NULL, 
TBIRTHDAY DATETIME NOT NULL, PROF VARCHAR(6), 
DEPART VARCHAR(10) NOT NULL);
# 向各表导入数据
INSERT INTO STUDENT (SNO,SNAME,SSEX,SBIRTHDAY,CLASS) VALUES 
(108 ,'曾华' ,'男' ,'1977-09-01',95033),
(105 ,'匡明' ,'男' ,'1975-10-02',95031),
(107 ,'王丽' ,'女' ,'1976-01-23',95033),
(101 ,'李军' ,'男' ,'1976-02-20',95033),
(109 ,'王芳' ,'女' ,'1975-02-10',95031),
(103 ,'陆君' ,'男' ,'1974-06-03',95031);
INSERT INTO COURSE(CNO,CNAME,TNO) VALUES 
('3-105' ,'计算机导论',825),
('3-245' ,'操作系统' ,804),
 ('6-166' ,'数据电路' ,856),
('9-888' ,'高等数学' ,100);
INSERT INTO SCORE(SNO,CNO,DEGREE) VALUES
(103,'3-245',86),
(105,'3-245',75),
 (109,'3-245',68),
 (103,'3-105',92),
(105,'3-105',88),
 (109,'3-105',76),
 (101,'3-105',64),
 (107,'3-105',91),
(108,'3-105',78),
 (101,'6-166',85),
 (107,'6-106',79),
 (108,'6-166',81);
INSERT INTO TEACHER(TNO,TNAME,TSEX,TBIRTHDAY,PROF,DEPART) VALUES 
(804,'李诚','男','1958-12-02','副教授','计算机系'),
 (856,'张旭','男','1969-03-12','讲师','电子工程系'),
(825,'王萍','女','1972-05-05','助教','计算机系'),
(831,'刘冰','女','1977-08-14','助教','电子工程系');

  我的答案和参考答案如下,若有两条解答,则第一条为我的解答,若只有一条解答,即为参考解答。

SELECT * from student;
SELECT * from course;
SELECT * from score;
SELECT * from teacher;
select * from grade;
1、 查询Student表中的所有记录的Sname、Ssex和Class列。 
select  s.sname,s.ssex,s.class  from student s;
SELECT SNAME,SSEX,CLASS FROM STUDENT;
2、 查询教师所有的单位即不重复的Depart列。 
select DISTINCT t.depart  from teacher t;
SELECT DISTINCT DEPART FROM TEACHER;
3、 查询Student表的所有记录。 
select * from student;
SELECT * FROM STUDENT;
4、 查询Score表中成绩在60到80之间的所有记录。 
select s.degree from score s where s.degree > 60 and s.degree < 80;
SELECT * FROM SCORE WHERE DEGREE BETWEEN 60 AND 80;
5、 查询Score表中成绩为85,86或88的记录。 
select s.degree from score s where s.degree = 85 or s.degree = 86 or s.degree = 88;
SELECT * FROM SCORE WHERE DEGREE IN (85,86,88);
6、 查询Student表中“95031”班或性别为“女”的同学记录。 
select * from student s where s.ssex = '女' or s.class='95031';
SELECT * FROM STUDENT WHERE CLASS=95031 OR SSEX='女';
7、 以Class降序查询Student表的所有记录。 
select * from student s ORDER BY s.class desc;
SELECT * FROM STUDENT ORDER BY CLASS DESC;
9、 查询“95031”班的学生人数。 
SELECT count(*) from student s where s.class='95031';
SELECT COUNT(*) NUMBER FROM STUDENT WHERE CLASS=95031;
10、查询Score表中的最高分的学生学号和课程号。 
select s.sno,c.cno  from student s INNER JOIN score c where s.sno = c.sno and  c.degree = (select MAX(DEGREE) from score )  ;
SELECT SNO,CNO FROM SCORE WHERE DEGREE=(SELECT MAX(DEGREE) FROM SCORE);
11、查询‘3-105’号课程的平均分。 
SELECT avg(s.degree) from score s where s.cno='3-105';
SELECT AVG(DEGREE) FROM SCORE WHERE CNO='3-105';
12、查询Score表中至少有5名学生选修的并以3开头的课程的平均分数。
SELECT AVG(s.degree) from score s GROUP BY s.cno HAVING count(s.cno) >= 5 and s.cno like '3%' ;
SELECT AVG(DEGREE),CNO FROM SCORE WHERE CNO LIKE '3%'
GROUP BY CNO HAVING COUNT(SNO)>=5;
14、查询所有学生的Sname、Cno和Degree列。 
SELECT s.sname,c.cno,c.degree from student s inner JOIN score c WHERE s.sno=c.sno;
SELECT P.SNAME,Q.CNO,Q.DEGREE 
FROM STUDENT P INNER JOIN SCORE Q ON P.SNO=Q.SNO;
16、查询所有学生的Sname、Cname和Degree列。--答案有误 
SELECT s.sname,c.cname,e.degree from student s INNER JOIN score e INNER JOIN course c where s.sno = e.sno and e.cno = c.cno;
SELECT AVG(DEGREE) 
FROM STUDENT A INNER JOIN SCORE B 
ON A.SNO=B.SNO 
WHERE A.CLASS=95033;
17、查询“95033”班所选课程的平均分。 
SELECT AVG(degree) FROM score where sno in (SELECT sno from student where class ='95033');
SELECT AVG(DEGREE) 
FROM STUDENT A INNER JOIN SCORE B 
ON A.SNO=B.SNO 
WHERE A.CLASS=95033;
18、假设使用如下命令建立了一个grade表: 
create table grade(low varchar(3),upp varchar(3),rank varchar(3)); 
insert into grade values(90,100,'A'); 
insert into grade values(80,89,'B'); 
insert into grade values(70,79,'C'); 
insert into grade values(60,69,'D'); 
insert into grade values(0,59,'E'); 
现查询所有同学的Sno、Cno和rank列。 
SELECT s.sno,s.cno,g.rank  from score s INNER JOIN grade g WHERE s.degree > g.low and s.degree < g.upp;
SELECT A.SNO,A.CNO,B.rank from score A ,grade B 
WHERE A.DEGREE>=B.low && A.DEGREE<=B.upp;
22、查询和学号为108的同学同年出生的所有学生的Sno、Sname和Sbirthday列。 
SELECT sno,sname,sbirthday from student where sbirthday = (SELECT sbirthday from student where sno='108');
SELECT * FROM STUDENT 
WHERE YEAR(SBIRTHDAY)=( 
SELECT YEAR(SBIRTHDAY) FROM STUDENT WHERE SNO=108)
23、查询“张旭“教师任课的学生成绩。 
SELECT e.sno,e.cno,e.degree from score e INNER JOIN course c INNER JOIN teacher t WHERE e.cno=c.cno and c.tno=t.tno and t.tname='张旭';
SELECT A.SNO,A.DEGREE 
FROM SCORE A JOIN (TEACHER B,COURSE C) 
ON A.CNO=C.CNO AND B.TNO=C.TNO 
WHERE B.TNAME='张旭';
24、查询选修某课程的同学人数多于5人的教师姓名。 
SELECT tname from teacher where tno in (SELECT tno from course where cno in (SELECT cno from score GROUP BY cno HAVING COUNT(cno)>5 ));
SELECT B.TNAME 
FROM SCORE A JOIN (TEACHER B,COURSE C) 
ON (A.CNO=C.CNO AND B.TNO=C.TNO) 
GROUP BY A.CNO HAVING COUNT(A.CNO)>5;
25、查询95033班和95031班全体学生的记录。 
SELECT * from student where class= '95033' or class='95031';
SELECT * FROM STUDENT WHERE CLASS IN (95033,95031);
26、查询存在有85分以上成绩的课程Cno. --
select cno from score GROUP BY cno HAVING max(degree)>85;
SELECT DISTINCT CNO FROM SCORE WHERE DEGREE>85;
29、查询选修编号为“3-105“课程且成绩至少高于选修编号为“3-245”的同学的Cno、Sno和Degree,并按Degree从高到低次序排序。
SELECT * FROM SCORE 
WHERE CNO='3-105' AND DEGREE>ANY( 
SELECT DEGREE FROM SCORE WHERE CNO='3-245') 
ORDER BY DEGREE DESC;
30、查询选修编号为“3-105”且成绩高于选修编号为“3-245”课程的同学的Cno、Sno和Degree.--
SELECT * FROM SCORE 
WHERE CNO='3-105' AND DEGREE>ALL( 
SELECT DEGREE FROM SCORE WHERE CNO='3-245');
32、查询所有“女”教师和“女”同学的name、sex和birthday. 
SELECT SNAME NAME,SSEX SEX,SBIRTHDAY BIRTHDAY FROM STUDENT ;
WHERE SSEX='女' 
UNION 
SELECT TNAME,TSEX,TBIRTHDAY FROM TEACHER 
WHERE TSEX='女';
34、查询所有任课教师的Tname和Depart. 
select t.tname name,t.depart depart from teacher t where t.tno in (select tno from course);
SELECT A.TNAME,A.DEPART FROM TEACHER A JOIN COURSE B ON A.TNO=B.TNO;
35 查询所有未讲课的教师的Tname和Depart. 
select t.tname name,t.depart depart from teacher t where t.tno not in (select tno from course);
SELECT TNAME,DEPART FROM TEACHER 
WHERE TNO NOT IN (SELECT TNO FROM COURSE);
36、查询至少有2名男生的班号。 
SELECT class from student where ssex='男' GROUP by class having count(*)>=2;
SELECT CLASS FROM STUDENT 
WHERE SSEX='男' 
GROUP BY CLASS HAVING COUNT(SSEX)>1;
38、查询Student表中每个学生的姓名和年龄。
SELECT sname, TIMESTAMPDIFF(YEAR, sbirthday, CURDATE()) age from student;
SELECT * FROM STUDENT WHERE NOT SNAME LIKE '王%';
39、查询Student表中最大和最小的Sbirthday日期值。 
SELECT min(sbirthday) max ,max(sbirthday) min from student;
SELECT SNAME,YEAR(NOW())-YEAR(SBIRTHDAY) AGE FROM STUDENT;SELECT * FROM student ORDER BY CLASS DESC,SBIRTHDAY;
41、查询“男”教师及其所上的课程。
SELECT t.tno,t.tname,t.tsex,c.cname from teacher t INNER JOIN course c where t.tsex='男' and t.tno=c.tno;
SELECT CNO,CNAME FROM COURSE 
WHERE TNO IN (SELECT TNO FROM TEACHER WHERE TSEX='男');
43、查询和“李军”同性别的所有同学的Sname. 
select sname FROM student where ssex = (SELECT ssex from student where sname='李军') ;
SELECT SNAME FROM student WHERE SSEX= 
(SELECT SSEX FROM STUDENT WHERE SNAME='李军');
44、查询和“李军”同性别并同班的同学Sname. 
select sname FROM student where ssex = (SELECT ssex from student where sname='李军') and class = (SELECT class from student where sname='李军');
SELECT SNAME FROM student WHERE (SSEX,CLASS)= 
(SELECT SSEX,CLASS FROM STUDENT WHERE SNAME='李军');
45、查询所有选修“计算机导论”课程的“男”同学的成绩表。
SELECT * from score c WHERE c.cno  in (SELECT cno from course where cname='计算机导论') and c.sno in (SELECT sno from student where ssex='男');
SELECT A.* FROM SCORE A JOIN(STUDENT B,COURSE C) 
ON A.SNO=B.SNO AND A.CNO=C.CNO 
WHERE B.SSEX='男' AND C.CNAME='计算机导论';
--不能用等于,因为子查询返回的结果可能不为一个

  接下来具体讨论做错的或者对题目理解不清的题。

8、 以Cno升序、Degree降序查询Score表的所有记录。-- 
SELECT * from score s ORDER BY s.sno asc , s.degree desc;
SELECT * FROM SCORE ORDER BY CNO,DEGREE DESC;

  1.这里明显看出给出的答案不正确,同时也表明使用逗号连接两个排序的字段。

13、查询最低分大于70,最高分小于90的Sno列。 --
SELECT sno from score where degree > 70 and degree < 90;
SELECT cno FROM SCORE WHERE DEGREE>70&&DEGREE<90;

  2.主要是在使用and和&&上的区别,都能达到效果。

15、查询所有学生的Sno、Cname和Degree列。-- 
SELECT s.sno,c.cname,e.degree from student s INNER JOIN score e INNER JOIN course c where s.sno = e.sno and e.cno = c.cno;
SELECT A.CNO,A.CNAME,B.DEGREE 
FROM COURSE A INNER JOIN SCORE B 
ON A.CNO=B.CNO; 
A.CNAME,B.DEGREE,C.SNAME 
FROM COURSE A INNER JOIN (SCORE B,STUDENT C) 
ON A.CNO=B.CNO AND B.SNO=C.SNO;

  3.两种方式都可以达到效果,我写的SQL格式不规范,需要美化SQL的格式。

19、查询选修“3-105”课程的成绩高于“109”号同学成绩的所有同学的记录。--
SELECT * from student where sno in (SELECT e.sno from score e where e.cno='3-105' and e.degree > (SELECT degree from score where sno = '109' and cno ='3-105'));
SELECT * FROM SCORE 
WHERE CNO='3-105' AND DEGREE> 
ALL(SELECT DEGREE FROM SCORE WHERE SNO=109 AND CNO='3-105'); 

   4.主要是对于分组的一个理解不同。

20、查询score中选学一门以上课程的同学中分数为非最高分成绩的记录。--
SELECT * from score s where s.degree != (select max(degree) from score) and s.sno not in (SELECT sno from score GROUP BY sno HAVING count(sno)=1);
SELECT * FROM SCORE 
WHERE DEGREE NOT IN 
(SELECT MAX(DEGREE) FROM SCORE 
GROUP BY SNO ) 
AND SNO IN 
(SELECT SNO FROM SCORE 
GROUP BY SNO HAVING COUNT(SNO)>1);

  5.标答的思路比较清晰。

21、查询成绩高于学号为“109”、课程号为“3-105”的成绩的所有记录。 --
SELECT * from score where degree > (SELECT degree from score where sno='109' and cno='3-105') and cno='3-105';
SELECT * FROM SCORE 
WHERE DEGREE>(SELECT DEGREE FROM SCORE 
WHERE SNO=109 AND CNO='3-105');

  6.区别在于是否加上对于课程号的限制,属于表意不明。

27、查询出“计算机系“教师所教课程的成绩表。-- 
SELECT e.sno,e.cno,e.degree from score e INNER JOIN course c INNER JOIN teacher t WHERE e.cno=c.cno and c.tno=t.tno and t.depart='计算机系';
SELECT A.SNO,A.CNO,A.DEGREE 
FROM SCORE A JOIN (TEACHER B,COURSE C)
ON A.CNO=C.CNO AND B.TNO=C.TNO 
WHERE DEPART='计算机系';
28、查询“计算机系”与“电子工程系“不同职称的教师的Tname和Prof。--
SELECT a.tname,a.prof from (SELECT * from teacher WHERE depart = '计算机系' or depart= '电子工程系') a GROUP BY a.prof HAVING count(a.prof)=1 ;
SELECT TNAME,PROF FROM TEACHER 
WHERE DEPART='计算机系' AND PROF NOT IN ( 
SELECT PROF FROM TEACHER WHERE DEPART='电子工程系');

  7.只比较了计算机系中与电子系不同的,没有比较电子系中与计算机系不同的,认为我的答案比较确切。

31、查询所有教师和同学的name、sex和birthday. --
select s.sname sname,s.ssex ssex,s.sbirthday sbirthday,t.tname tname,t.tsex tsex,t.tbirthday tbirthday  from student s INNER JOIN teacher t;
SELECT SNAME,SSEX,SBIRTHDAY FROM STUDENT 
UNION 
SELECT TNAME,TSEX,TBIRTHDAY FROM TEACHER;

   8.忘记了union的用法,连接是两个表的字段进行左右连接,而union则是相对于进行上下的连接。

33、查询成绩比该课程平均成绩低的同学的成绩表。--
SELECT * from score c GROUP BY c.cno HAVING c.degree < avg(c.degree);
SELECT A.* FROM SCORE A INNER JOIN 
(SELECT CNO,AVG(DEGREE) AVG 
FROM SCORE GROUP BY CNO) B 
ON A.CNO=B.CNO 
WHERE DEGREE<AVG;

  9.标答的思路比较清晰,对于子查询用的比较好,值得学习

37、查询Student表中不姓“王”的同学记录。 --
select * from student where sname not like '王%';
SELECT * FROM STUDENT WHERE NOT SNAME LIKE '王%';

  10.殊途同归,只是把not位置提前了,可以学习这种写法。

40、以班号和年龄从大到小的顺序查询Student表中的全部记录。--
SELECT * from student ORDER BY sno desc ,sbirthday asc;
SELECT * FROM student ORDER BY CLASS DESC,SBIRTHDAY;

  11.值得注意年龄的大小和出生日期大小之间的关系。

42、查询最高分同学的Sno、Cno和Degree列。--
SELECT * from score GROUP BY cno HAVING degree=max(degree);
SELECT SNO,CNO,DEGREE 
FROM SCORE WHERE DEGREE=(SELECT MAX(DEGREE) FROM SCORE);

  12.有一个是否分组的差异,存在一定的争论。

38、查询Student表中每个学生的姓名和年龄。
SELECT sname, TIMESTAMPDIFF(YEAR, sbirthday, CURDATE()) age from student;
SELECT SNAME,YEAR(NOW())-YEAR(SBIRTHDAY) AGE FROM STUDENT;SELECT * FROM student ORDER BY CLASS DESC,SBIRTHDAY;

  13.通过datetime类型的值求年龄,我的是实际年龄,标答是虚岁。

  接下来还会有一篇SQL的进阶篇,拭目以待。



猜你喜欢

转载自blog.csdn.net/qq_32801733/article/details/80316364