SQL语句练习

前言

通过一个最经典的“教师-学生-成绩”表来练习SQL语句。
各表之间的关系:
在这里插入图片描述

一、构建表和数据

# 新建一个Student表
DROP TABLE IF EXISTS STUDENT;
CREATE TABLE STUDENT(
SNO VARCHAR(3) PRIMARY KEY,
SNAME VARCHAR(10) NOT NULL,
SSEX VARCHAR(2) NOT NULL,
SBIRTHDAY DATETIME  DEFAULT NULL,
CCLASS VARCHAR(5) DEFAULT NULL
)CHARSET = utf8;

# 添加Student表数据
INSERT INTO STUDENT VALUES 
('108','曾华','男','1977-09-01 00:00:00','95033'),
('105','匡明','男','1975-10-02 00:00:00','95031'),
('107','王丽','女','1976-01-23 00:00:00','95033'),
('101','李军','男','1976-02-20 00:00:00','95033'),
('109','王芳','女','1975-02-10 00:00:00','95031'),
('103','陆君','男','1974-06-03 00:00:00','95031');

# 新建一个Score表
DROP TABLE IF EXISTS SCORE;
CREATE TABLE SCORE(
SNO VARCHAR(3) NOT NULL,
CNO VARCHAR(5) NOT NULL,
DEGREE DECIMAL(10,1) NOT NULL
)CHARSET = utf8;

# 添加score表数据
INSERT INTO SCORE VALUES 
('103','3-245',86.0),
('105','3-245',75.0),
('109','3-245',68.0),
('103','3-105',92.0),
('105','3-105',88.0),
('109','3-105',76.0),
('101','3-105',64.0),
('107','3-105',91.0),
('101','6-166',85.0),
('107','6-106',79.0),
('108','3-105',78.0),
('108','6-166',81.0);


# 新建一个Course表
DROP TABLE IF EXISTS COURSE;
CREATE TABLE COURSE(
CNO VARCHAR(5) NOT NULL,
CNAME VARCHAR(10) NOT NULL,
TNO VARCHAR(10) NOT NULL
)CHARSET=utf8;

# 添加course表数据
INSERT INTO COURSE VALUES 
('3-105','计算机导论','825'),
('3-245','操作系统','804'),
('6-166','数据电路','856'),
('9-888','高等数学','100');

# 新建一个Teacher表
DROP TABLE IF EXISTS 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) DEFAULT NULL,
DEPART VARCHAR(10) NOT NULL
)CHARSET = utf8;

# 添加teacher表数据
INSERT INTO teacher VALUES
('804','李诚','男','1958-12-02 00:00:00','副教授','计算机系'),
('856','张旭','男','1969-03-12 00:00:00','讲师','电子工程系'),
('825','王萍','女','1972-05-05 00:00:00','助教','计算机系'),
('831','刘冰','女','1977-08-14 00:00:00','助教','电子工程系');

二、练习题目

# 1、查询Student表中的所有记录的Sname、Ssex和Class列
SELECT Sname,Ssex,Cclass FROM student;

# 2、查询教师所有的单位即不重复的Depart列。
SELECT DISTINCT depart FROM teacher;

# 3、查询Student表的所有记录。
SELECT *FROM student;

# 4、查询Score表中成绩在60到80之间的所有记录。
SELECT *
FROM score 
WHERE degree>60 AND degree<80;

# 5、查询Score表中成绩为85,86或88的记录
SELECT *
FROM score
WHERE degree=86 OR degree=86 OR degree=88;

# 6、查询Student表中“95031”班或性别为“女”的同学记录
SELECT *
FROM student
WHERE CCLASS='95031' OR SSEX='女';

# 7、以Class降序查询Student表的所有记录
SELECT *
FROM student 
ORDER BY CCLASS DESC;

# 8、以Cno升序、Degree降序查询Score表的所有记录。
SELECT *
FROM score
ORDER BY Cno ASC,DEGREE DESC;

# 9、查询“95031”班的学生人数。
SELECT COUNT(*) AS studentNum 
FROM student 
WHERE CCLASS='95031';

# 10、查询Score表中的最高分的学生学号和课程号。
SELECT Sno,Cno
FROM score
WHERE degree=(
SELECT MAX(degree)
FROM score);

# 11、查询‘3-105’号课程的平均分。
SELECT AVG(degree)
FROM score
WHERE cno='3-105';

# 12、查询Score表中至少有5名学生选修的并以3开头的课程的平均分数。
SELECT AVG(degree),cno
FROM score
WHERE cno LIKE '3%' 
AND 
cno IN (
SELECT cno
FROM score GROUP BY cno 
HAVING COUNT(cno)>5);

SELECT
  AVG(DEGREE),
  CNO
FROM SCORE
WHERE cno LIKE '3%'
GROUP BY CNO
HAVING COUNT(*) > 5;

# 13、查询最低分大于70,最高分小于90的Sno列。
SELECT Sno
FROM score
GROUP BY Sno
HAVING 
MAX(degree)<90 AND MIN(degree)>70;

# 14、查询所有学生的Sname、Cno和Degree列。
SELECT Sname,Cno,Degree
FROM student,score
WHERE student.sno = score.sno;

# 15、查询所有学生的Sno、Cname和Degree列。
SELECT score.sno,Cname,Degree
FROM student,score,course
WHERE student.`SNO` = score.`SNO`
AND score.`CNO` = course.`CNO`;

# 16、查询所有学生的Sname、Cname和Degree列。
SELECT sname,cname,degree # 使用隐式内连接
FROM student,score,course
WHERE student.`SNO` = score.`SNO`
AND score.`CNO` = course.`CNO`;

SELECT sname,cname,degree # 使用显示内连接
FROM student INNER JOIN (score,course)
ON student.`SNO` = score.`SNO`
AND score.`CNO` = course.`CNO`;

# 17、查询“95033”班所选课程的平均分。
SELECT AVG(degree)
FROM score JOIN student 
ON score.`SNO`=student.`SNO`
GROUP BY Cclass
HAVING Cclass = '95033';
SELECT * FROM score JOIN student ON score.`SNO`=student.`SNO`;

SELECT AVG(degree)
FROM score
WHERE sno IN (
	SELECT sno
	FROM student
	WHERE Cclass ='95033');
	

# 18、假设使用如下命令建立了一个grade表:
CREATE TABLE grade (
  low  NUMERIC(3, 0),
  upp  NUMERIC(3),
  rank CHAR(1)
);
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 A.Sno,A.Cno,B.rank,A.`DEGREE`
FROM score A,grade B
WHERE A.`DEGREE` BETWEEN B.`low` AND B.`upp`;

# 19、查询选修“3-105”课程的成绩高于“109”号同学成绩的所有同学的记录。
SELECT *
FROM score
WHERE cno='3-105' AND degree> ALL(
	SELECT degree
	FROM score
	WHERE sno='109'
	);

# 20、查询score中选学一门以上课程的同学中分数为非最高分成绩的学生记录
SELECT *FROM student 
WHERE sno IN(
	SELECT sno
	FROM score
	WHERE degree<(SELECT MAX(degree) FROM score)
	GROUP BY cno
	HAVING COUNT(*)>1);

# 21、查询成绩高于学号为“109”、课程号为“3-105”的成绩的所有记录。

SELECT *
FROM score
WHERE cno='3-105' AND degree>ALL(
	SELECT degree
	FROM score
	WHERE sno='109');

# 22、查询和学号为108的同学同年出生的所有学生的Sno、Sname和Sbirthday列。
SELECT Sno,Sname,Sbirthday
FROM student
WHERE YEAR(Sbirthday)=(
	SELECT YEAR(sbirthday)
	FROM student 
	WHERE sno='108');

# 23、查询“张旭“教师任课的学生成绩。
SELECT *
FROM score
WHERE cno IN(
	SELECT cno
	FROM course
	WHERE TNO IN(
	SELECT TNO FROM teacher WHERE teacher.`TNAME`='张旭')
	)
	

SELECT *
FROM score
WHERE cno IN(
	SELECT cno
	FROM course 
	INNER JOIN teacher
	ON course.`TNO`=teacher.`TNO`
	WHERE teacher.`TNAME`='张旭');
	
# 24、查询选修某课程的同学人数多于5人的教师姓名。
SELECT teacher.TNAME tname
FROM teacher INNER JOIN course
ON teacher.`TNO`=course.`TNO`
WHERE cno IN(
	SELECT cno FROM score
	GROUP BY cno
	HAVING COUNT(*)>5);


SELECT TNAME
FROM TEACHER
WHERE TNO = (
  SELECT TNO
  FROM COURSE
  WHERE CNO = (SELECT CNO
               FROM SCORE
               GROUP BY CNO
               HAVING COUNT(SNO) > 5)
);

# 25、查询95033班和95031班全体学生的记录。
SELECT *
FROM student
WHERE CCLASS='95033' OR CCLASS='95031';

SELECT *
FROM student
WHERE CCLASS IN('95033','95031');

# 26、查询存在有85分以上成绩的课程Cno.
SELECT cno
FROM score
GROUP BY cno
HAVING MAX(degree)>86;

# 27、查询出“计算机系“教师所教课程的成绩表。
SELECT *
FROM score
WHERE score.`CNO` IN(
	SELECT cno
	FROM teacher INNER JOIN course
	ON teacher.`TNO`=course.`TNO`
	WHERE DEPART ='计算机系');

# 28、查询“计算机系”中与“电子工程系“不同职称的教师的Tname和Prof
SELECT Tname,Prof
FROM teacher
WHERE DEPART='计算机系' AND prof NOT IN(
	SELECT PROF
	FROM teacher
	WHERE DEPART='电子工程系');

# 29、查询选修编号为“3-105“课程且成绩至少高于选修编号为“3-245”的同学的Cno、Sno和Degree,并按Degree从高到低次序排序。
SELECT Cno,Sno,Degree
FROM score
WHERE cno='3-105' AND degree>ANY(
	SELECT degree
	FROM score
	WHERE score.`CNO`='3-245')
ORDER BY degree DESC;

# 30、查询选修编号为“3-105”且成绩高于选修编号为“3-245”课程的同学的Cno、Sno和Degree.
SELECT Cno,Sno,Degree
FROM score
WHERE cno='3-105' AND degree>ALL(
	SELECT degree
	FROM score
	WHERE score.`CNO`='3-245')
ORDER BY degree DESC;

# 31、查询所有教师和同学的name、sex和birthday.
SELECT 
	Tname NAME,
	Tsex sex,
	TBIRTHDAY birthday
FROM teacher
UNION
SELECT 
	Sname NAME,
	Ssex sex,
	SBIRTHDAY birthday
FROM student;

# 32、查询所有“女”教师和“女”同学的name、sex和birthday.
SELECT
	tname NAME,
	tsex sex,
	tbirthday birthday
FROM teacher
WHERE tsex='女'
UNION
SELECT
	sname NAME,
	ssex sex,
	SBIRTHDAY birthday
FROM student
WHERE ssex='女';

# 33、查询成绩比该课程平均成绩低的同学的成绩表。
SELECT *
FROM score A
WHERE degree<(
	SELECT AVG(degree)
	FROM score B
	WHERE A.`CNO`=B.`CNO`);
	
SELECT score.*
FROM score JOIN(
	SELECT cno,AVG(degree) mean
	FROM score
	GROUP BY cno)AS B
ON score.`CNO`=B.cno
WHERE degree< mean;

# 34、查询所有任课教师的Tname和Depart.
 SELECT Tname,Depart
 FROM teacher
 WHERE TNO IN(
	SELECT TNO
	FROM course)

  
# 35、查询所有未讲课的教师的Tname和Depart.
SELECT Tname,Depart
FROM teacher
WHERE TNO NOT IN(
	SELECT TNO
	FROM course);

# 36、查询至少有2名男生的班号。
SELECT cclass
FROM student
WHERE ssex='男' # 分组前先进行筛选,不满足不进行分组
GROUP BY cclass
HAVING COUNT(cclass)>=2

# 37、查询Student表中不姓“王”的同学记录。
SELECT *
FROM student
WHERE sname NOT IN(
	SELECT sname
	FROM student
	WHERE sname LIKE '王%');
	
# 38、查询Student表中每个学生的姓名和年龄。
SELECT sname NAME,YEAR(NOW())-YEAR(SBIRTHDAY) age
FROM student;

# 39、查询Student表中最大和最小的Sbirthday日期值。
SELECT MAX(sbirthday),MIN(sbirthday)
FROM student;

# 40、以班号和年龄从大到小的顺序查询Student表中的全部记录。
SELECT *
FROM student
ORDER BY cclass DESC,YEAR(NOW()-YEAR(sbirthday)) DESC;

# 41、查询“男”教师及其所上的课程。
SELECT *
FROM course
WHERE tno IN(
	SELECT tno
	FROM teacher
	WHERE Tsex='男');

SELECT course.*
FROM course INNER JOIN teacher
ON course.`TNO`=teacher.`TNO`
WHERE tsex='男';

# 42、查询每门课最高分同学的Sno、Cno和Degree列。
SELECT score.Sno,score.Cno,score.Degree
FROM score INNER JOIN(
	SELECT cno,MAX(degree) maxdegree
	FROM score
	GROUP BY cno
	)AS A
ON score.`CNO`=A.cno
WHERE degree=maxdegree;

# 43、查询和“李军”同性别的所有同学的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 cclass=(
	SELECT cclass
	FROM student
	WHERE sname='李军'
	);

SELECT sname
FROM student
WHERE (ssex,cclass)=(
	SELECT ssex,cclass
	FROM student
	WHERE sname='李军'
	);

# 45、查询所有选修“计算机导论”课程的“男”同学的成绩表
SELECT *
FROM score
WHERE sno IN(
	SELECT sno
	FROM student
	WHERE ssex='男'
	)
AND cno=(
	SELECT cno
	FROM course
	WHERE cname='计算机导论'
	)

# 46、使用游标方式来同时查询每位同学的名字,他所选课程及成绩。
SELECT S.SNO,S.SNAME,C.CNAME,SC.DEGREE AS DEGREE
FROM STUDENT S, COURSE C, SCORE SC
WHERE S.SNO=SC.SNO
AND SC.CNO=C.CNO;

# 47、 声明触发器指令,每当有同学转换班级时执行触发器。
DELIMITER || # 该命令可以声明||为指令结束符号
CREATE TRIGGER display_class_changes AFTER UPDATE
ON student 
FOR EACH ROW 
BEGIN #触发器被触发时执行的操作,不能有返回值(不能是查询语句)
   INSERT INTO grade(low,upp,rank) VALUE(0,1,'V');
END; 
||

DROP TRIGGER display_class_changes; # 删除触发器

# 执行该语句可以触发触发器的响应
UPDATE student
SET cclass='95031'
WHERE sno='108';

# 48、修改“李军”的性别为女。
UPDATE student
SET ssex='女'
WHERE sname='李军';

# 48、删除grade表中,rank为‘V’的数据
DELETE 
FROM grade
WHERE rank='V';

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值