SQL——基础语句练习

主要是针对,一些经常遇到的SQL语句,进行了初步的总结。可以检验对sql的学习程度,对SQL语句进行进一步巩固以及加强。

准备工作

  • 首先需要创建四个表,分别是:student(学生表),teacher(教师表),score(成绩表),course(课程表)
  • 建表SQL以及初始数据预置
  • student:
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for student
-- ----------------------------
DROP TABLE IF EXISTS `student`;
CREATE TABLE `student`  (
  `stuNo` int(10) NOT NULL,
  `stuName` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL,
  `stuSex` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL,
  `stuAge` int(255) DEFAULT NULL,
  PRIMARY KEY (`stuNo`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;

-- ----------------------------
-- Records of student
-- ----------------------------
INSERT INTO `student` VALUES (1, '张一', '男', 15);
INSERT INTO `student` VALUES (2, '张二', '女', 35);
INSERT INTO `student` VALUES (3, '张三', '女', 27);
INSERT INTO `student` VALUES (4, '张四', '男', 15);

SET FOREIGN_KEY_CHECKS = 1;
  • teacher:
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for teacher
-- ----------------------------
DROP TABLE IF EXISTS `teacher`;
CREATE TABLE `teacher`  (
  `teaNo` int(11) NOT NULL,
  `teaName` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL,
  PRIMARY KEY (`teaNo`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;

-- ----------------------------
-- Records of teacher
-- ----------------------------
INSERT INTO `teacher` VALUES (1, '孙一');
INSERT INTO `teacher` VALUES (2, '孙二');

SET FOREIGN_KEY_CHECKS = 1;
  • score:
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for score
-- ----------------------------
DROP TABLE IF EXISTS `score`;
CREATE TABLE `score`  (
  `id` int(11) NOT NULL,
  `stuNo` int(11) DEFAULT NULL,
  `cNo` int(11) DEFAULT NULL,
  `score` int(255) DEFAULT NULL,
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;

-- ----------------------------
-- Records of score
-- ----------------------------
INSERT INTO `score` VALUES (1, 1, 1, 60);
INSERT INTO `score` VALUES (2, 1, 2, 25);
INSERT INTO `score` VALUES (3, 1, 3, 56);
INSERT INTO `score` VALUES (4, 1, 4, 100);
INSERT INTO `score` VALUES (5, 1, 5, 63);
INSERT INTO `score` VALUES (6, 2, 1, 5);
INSERT INTO `score` VALUES (7, 2, 2, 29);
INSERT INTO `score` VALUES (8, 2, 3, 59);
INSERT INTO `score` VALUES (9, 2, 4, 60);
INSERT INTO `score` VALUES (10, 2, 5, 65);
INSERT INTO `score` VALUES (11, 3, 1, 60);
INSERT INTO `score` VALUES (12, 3, 2, 100);
INSERT INTO `score` VALUES (13, 3, 3, 88);
INSERT INTO `score` VALUES (14, 3, 4, 75);
INSERT INTO `score` VALUES (15, 3, 5, 65);
INSERT INTO `score` VALUES (16, 4, 1, 60);
INSERT INTO `score` VALUES (17, 4, 2, 57);
INSERT INTO `score` VALUES (18, 4, 3, 86);
INSERT INTO `score` VALUES (19, 4, 4, 73);
INSERT INTO `score` VALUES (20, 4, 5, 62);

SET FOREIGN_KEY_CHECKS = 1;
  • course:
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for course
-- ----------------------------
DROP TABLE IF EXISTS `course`;
CREATE TABLE `course`  (
  `cNo` int(11) NOT NULL,
  `cName` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL,
  `cTeacher` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL,
  PRIMARY KEY (`cNo`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;

-- ----------------------------
-- Records of course
-- ----------------------------
INSERT INTO `course` VALUES (1, '数学', '1');
INSERT INTO `course` VALUES (2, '语文', '1');
INSERT INTO `course` VALUES (3, '英语', '2');
INSERT INTO `course` VALUES (4, '美术', '2');
INSERT INTO `course` VALUES (5, '音乐', '2');

SET FOREIGN_KEY_CHECKS = 1;

表说明

针对上面所创建的四个表的属性进行说明。

  • Student学生表:主要四个属性 StuNo(主键)学生的学号,stuName 学生的姓名,stuSex 学生的性别,stuAge 学生的年纪
    image
  • teacher老师表:主要就两个属性:teaNo(主键)老师的工号,teaName 老师的姓名
    image
  • score成绩表:主要就四个属性:id(主键),stuNo(与学生表关联)学生的学号,cNo(与课程表关联)课程号,score 成绩
    image
  • course 课程表:cNo(主键)课程号,cName课程名称,cTeacher(和教师表关联)教师工号
    image

经典SQL语句练习

建议大家还是先自己尝试解决,遇到困难再去看解析和具体的代码,要是有更好的想法或者不同的意见欢迎大家在评论区进行讨论

  • 查询“1”课程比“2”课程成绩高的所有学生的学号
select a.stuNo from score a,score b where a.cNo='1'and b.cNo='2' and  a.stuNo=b.stuNo and a.score>b.score;

这个比较简单,主要就是从两个表里读取数据,通过学号相等来进行查找。

  • 查询平均成绩大于60分的同学的学号和平均成绩
select stuNo,AVG(score) from score group by stuNo  having avg(score)>60  ;

首先使用AVG这个函数来取平均值,然后使用group by进行分组

  • 查询所有同学的学号、姓名、选课数、总成绩
select a.stuNo,a.stuName,count(cNo),sum(score) from student a,score b  where a.stuNo=b.stuNo  group by a.stuNo,a.stuName  ;

和上面那个差不多,主要使用count进计数和sum进行求和

  • 查询姓“孙”的老师的个数
SELECT count(teaName) ,'孙'as 'Name'from teacher WHERE teaName like '孙%'

主要使用like相似查询,并且使用%进行适配,以及使用as来显示

  • 查询没学过“孙一”老师课的同学的学号、姓名
select stuName from student where stuNo not in (select stuNo from score where cNo in(select a.cNo from course a,teacher b where b.teaNo=a.cTeacher and b.teaName ='孙一'))

主要分为三个步骤:首先先查询孙一老师教什么课,然后再使用in查询什么学生上过这些课,然后使用not in查询没有包含在这些里面的学生。

  • 查询课程编号“2”的成绩比课程编号“1”课程低的所有同学的学号、姓名
方法一:
SELECT a.stuNo,a.stuName from student a,score b ,score c WHERE a.stuNo=b.stuNo and a.stuNo=c.stuNo and b.cNo='2'and c.cNo='1'and b.score <  c.score;
方法二:
select stuNo,stuName from student  where stuNo in   (select a.stuNo from score a,score b  where a.cNo='1' and b.cNo='2' and a.stuNo=b.stuNo and a.score>b.score)

第一个方法和第一个差不多。就是多了进行成绩的比较

第二个方法就是换了个写法来进行操作

  • 查询没有学全所有课的同学的学号、姓名
SELECT  a.stuNO,a.stuName FROM student a, score b WHERE a.stuNo=b.stuNo  group by b.stuNo having count(b.cNo)<(select count(cNo) from course)

就是学生选的课的总数和课程总数进行比较,

  • 查询至少有一门课与学号为“1”的同学所学相同的同学的学号和姓名
select distinct a.stuNo,stuName from student a,score b  where a.stuNo=b.stuNo and cNo in (select cNo from score where stuNo='1')

先把学号一的学生选的课找出来,然后进行查找

  • 查询各科成绩最高和最低的分:以如下形式显示:课程ID,最高分,最低分
select  cNo,max(score) as 最高分,min(score) as 最低分 from score  group by cNo
  • 删除“2”同学的“1”课程的成绩
delete from score where stuNo='2' and cNo='1'
  • 查询和" 01 "号的同学学习的课程完全相同的其他同学的信息
SELECT * from student WHERE stuNo in (SELECT  stuNo FROM score WHERE cNo in(SELECT distinct cNo FROM score WHERE stuNo='01')and stuNo<>'01'GROUP BY stuNo having count(cNo)>=4);
  • 查询两门及其以上不及格课程的同学的学号,姓名及其平均成绩
select a.stuNo,a.stuName,b.平均成绩 FROM student a right join (select stuNo,AVG(score)平均成绩 from score where score<60 group by stuNo having COUNT(score)>=2)b on a.stuNo=b.stuNo;
  • 查询各科成绩最高分、最低分和平均分:以如下形式显示:课程 ID ,课程 name ,最高分,最低分,平均分,及格率,中等率,优良率,优秀率及格为>=60,中等为:70-80,优良为:80-90,优秀为:>=90
select distinct A.cNo,cName,最高分,最低分,平均分,及格率,中等率,优良率,优秀率 from score A
left join Course on A.cNo=course.cNo
left join (select cNo,MAX(score)最高分,MIN(score)最低分,AVG(score)平均分 from score group by cNo)B on A.cNo=B.cNo
left join (select cNo,(((sum(case when score>=60 then 1 else 0 end)*1.00)/COUNT(*))*100)及格率 from score group by cNo)C on A.cNo=C.cNo
left join (select cNo,(((sum(case when score >=70 and score<80 then 1 else 0 end)*1.00)/COUNT(*))*100)中等率 from score group by cNo)D on A.cNo=D.cNo
left join (select cNo,(((sum(case when score >=80 and score<90 then 1 else 0 end)*1.00)/COUNT(*))*100)优良率 from score group by cNo)E on A.cNo=E.cNo
left join (select cNo,(((sum(case when score >=90 then 1 else 0 end)*1.00)/COUNT(*))*100)优秀率 
from score group by cNo)F on A.cNo=F.cNo
  • 按各科成绩进行排序,并显示排名,Score 重复时保留名次空缺(不保留)
保留
select *,RANK()over(order by score desc)排名 from score;
不保留
select *,DENSE_RANK()over(order by score desc)排名 from score
  • 查询学生的总成绩,并进行排名,总分重复时保留名次空缺
select *,RANK()over(order by 总成绩 desc)排名 from(
select stuNo,SUM(score)总成绩 from score group by stuNo)A
  • 查询各科成绩前三名的记录
select * from(select *,rank()over (partition by stuNo order by score desc)A from score)B where B.A<=3
select * from score a where (select COUNT(*) from score where cNo=a.cNo and score>a.score)<3 order by a.cNo,a.score desc

如何提高SQL查找效率

  • select子句中尽量避免使用*

    • 另外select * 用于多表联结,会造成更大的成本开销
  • where子句比较符号左侧避免函数,移到右边

  • 尽量避免使用in和not in

  • 尽量避免使用or,用union来代替

  • 善用limit子句限制返回的数据行数

要是各位看官感兴趣的话,后续会出几篇针对sql优化的文章。

最后

  • 如果觉得看完有收获,希望能给我点个赞,这将会是我更新的最大动力,感谢各位的支持
  • 欢迎各位关注我的公众号【java冢狐】,专注于java和计算机基础知识,保证让你看完有所收获,不信你打我
  • 如果看完有不同的意见或者建议,欢迎多多评论一起交流。感谢各位的支持以及厚爱。

image

猜你喜欢

转载自blog.csdn.net/issunmingzhi/article/details/110918192