面向考试数据库—单表查询(包含建表数据)

在这里插入图片描述
面向考试数据库系列博客以笔者的思维脑图为主线,博文内容为笔者对导图的具体分支所作的详细阐述,其中不足,望读者多加指正。

引言

  学习了一段时间SQL语言之后,其中操作了解到了很多,笔者按照上述脑图进行现阶段的SQL学习,到此在单表查询处涉及到了许多的SQL语句操作,故做此文作为笔记总结之用,其中也插入31到SQL查询例题进行求解阐述,希望帮助读者对知识进行更好的消化。主要内容如下:
在这里插入图片描述

● 建立练习数据库(之后习题亦是基于该库)

  开始正文前,读者需要先了解博客使用的库表结构;该库为一个选课库,主要库内容如下图所示:
在这里插入图片描述

建表源码

SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for course
-- ----------------------------
DROP TABLE IF EXISTS `course`;
CREATE TABLE `course`  (
  `Cno` char(4) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
  `Cname` char(40) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
  `Cpno` char(4) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
  `Ccredit` smallint(6) NULL DEFAULT NULL,
  PRIMARY KEY (`Cno`) USING BTREE,
  INDEX `Cpno`(`Cpno`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;

-- ----------------------------
-- Records of course
-- ----------------------------
INSERT INTO `course` VALUES ('1', '数据库', '5', 4);
INSERT INTO `course` VALUES ('2', '数学', NULL, 2);
INSERT INTO `course` VALUES ('3', '信息系统', '1', 4);
INSERT INTO `course` VALUES ('4', '操作系统', '6', 3);
INSERT INTO `course` VALUES ('5', '数据结构', '7', 4);
INSERT INTO `course` VALUES ('6', '数据处理', NULL, 2);
INSERT INTO `course` VALUES ('7', 'PASCAL语言\r', '6', 4);

-- ----------------------------
-- Table structure for sc
-- ----------------------------
DROP TABLE IF EXISTS `sc`;
CREATE TABLE `sc`  (
  `Sno` char(9) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '学号',
  `Cno` char(4) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '课程号',
  `Grade` smallint(255) NULL DEFAULT NULL COMMENT '成绩\r\n',
  PRIMARY KEY (`Sno`, `Cno`) USING BTREE,
  CONSTRAINT `Sno` FOREIGN KEY (`Sno`) REFERENCES `student` (`Sno`) ON DELETE RESTRICT ON UPDATE RESTRICT
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;

-- ----------------------------
-- Records of sc
-- ----------------------------
INSERT INTO `sc` VALUES ('200215121', '1', 92);
INSERT INTO `sc` VALUES ('200215121', '2', 85);
INSERT INTO `sc` VALUES ('200215121', '3', 88);
INSERT INTO `sc` VALUES ('200215122', '2', 90);
INSERT INTO `sc` VALUES ('200215122', '3', 80);

-- ----------------------------
-- Table structure for student
-- ----------------------------
DROP TABLE IF EXISTS `student`;
CREATE TABLE `student`  (
  `Sno` char(9) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
  `Sname` char(20) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `Ssex` char(2) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `Sage` smallint(6) NULL DEFAULT NULL,
  `Sdept` char(20) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  PRIMARY KEY (`Sno`) USING BTREE,
  UNIQUE INDEX `Sname`(`Sname`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;

-- ----------------------------
-- Records of student
-- ----------------------------
INSERT INTO `student` VALUES ('200215121', '李勇', '男', 20, 'CS');
INSERT INTO `student` VALUES ('200215122', '刘晨', '女', 19, 'CS');
INSERT INTO `student` VALUES ('200215123', '王敏', '女', 18, 'MA');

SET FOREIGN_KEY_CHECKS = 1;

单表查询知识点汇总

 关于单表查询的主要操作,主要可以分为5类“题型”。想要熟练的掌握解决好这几类题型,基础知识必需要扎实,关于单表的基础知识,笔者总结如下了内容。
 首先是常用的查询条件;
在这里插入图片描述
 其次要注意的是一些细节性的知识点;

  1. 关于排序 ;
    可以按一个或多个属性列排序
    .升序:ASC;降序:DESC;缺省值为升序
    当排序列含空值时
    .ASC:排序列为空值的元组最后显示
    .DESC:排序列为空值的元组最先显示

  2. 关于计数;
    COUNT([DISTINCT|ALL] *)
    COUNT([DISTINCT|ALL] <列名>)
    计算总和
    SUM([DISTINCT|ALL] <列名>)
    计算平均值
    AVG([DISTINCT|ALL] <列名>)
    最大最小值
    MAX([DISTINCT|ALL] <列名>)
    MIN([DISTINCT|ALL] <列名>)
    DISTINCT短语:在计算时要取消指定列中的重复值
    ALL短语:不取消重复值
    ALL为缺省值

  3. 关于分组;
    group by 细化聚集函数的作用对象 未对查询结果分组,聚集函数将作用于整个查询结果
    对查询结果分组后,聚集函数将分别作用于每个组 按指定的一列或多列值分组,值相等的为一组 HAVING短语与WHERE子句的区别;
    作用对象不同 WHERE子句作用于基表或视图,从中选择满足条件的元组 HAVING短语作用于组,从中选择满足条件的组。

  4. 关于通配符匹配问题;
    通配符匹配(% (百分号) 代表任意长度(长度可以为0)的字符串;_ (下横线) 代表任意单个字符);
    使用换码字符将通配符转义为普通字符( ESCAPE ‘\’ 表示“ \” 为换码字符 )这里笔者使用的查询工具不需要使用到ESCAPE ,用到\即可;
    涉及空值的查询( “IS” 不能用 “=” 代替)。

  5. 关于多重条件查询;
    多重条件查询(AND的优先级高于OR;可以用括号改变优先级;可用来实现多种其他谓词)。

    扫描二维码关注公众号,回复: 11139609 查看本文章

单表查询练习题32道

有了这些知识,我们就可以去尝试上手解决关于单表查询的32到例题了,关于例题的,笔者先给出脑图分布。
在这里插入图片描述

(1)选取表中的若干列

#例子1:查询全体学生的学号与姓名。
SELECT Sno,Sname FROM Student;

#例子2:查询全体学生的姓名、学号、所在系。
SELECT Sname,Sno,Sdept FROM student;

#[例3]  查询全体学生的详细记录。
SELECT  * FROM Student;

#[例4]  查全体学生的姓名及其出生年份。
SELECT Sname,2004-Sage AS BIRTH    /*假定当年的年份为2004年*/ FROM Student;

[5]  查询全体学生的姓名、出生年份和所有系,要求用小写字母表示所有系名
SELECT Sname,2004-Sage AS 'year of Brith',LOWER(Sdept) FROM student;

使用列别名改变查询结果的列标题:
SELECT Sname NAME ,'year of Brith:' BRITH,2004-Sage Brithday ,LOWER(Sdept) Department FROM student;

(2)选择表中若干元祖

 这类题型在单表查询中设计的知识点最多,也是最需要注意的。

#普通选取
[6]  查询选修了课程的学生学号。(取消重复行)
SELECT DISTINCT Sno FROM sc;

查询选修课程的各种成绩
 SELECT DISTINCT Cno,Grade FROM SC; 
 
 #大小比较
 [例7]  查询计算机科学系全体学生的名单。
 SELECT Sname
    FROM Student
    WHERE Sdept='CS';
		
	[8]  查询所有年龄在20岁以下的学生姓名及其年龄。
	SELECT Sname,Sage 
FROM    Student    
WHERE Sage < 20;

[例9]  查询考试成绩有不及格的学生的学号。
 SELECT DISTINCT Sno
    FROM  SC
    WHERE Grade<60;
		
#范围选取
[10] 查询年龄在20~23岁(包括20岁和23岁)之间的学生的姓名、系别和年龄
 SELECT Sname,Sdept,Sage
FROM     Student
WHERE   Sage BETWEEN 20 AND 23;

[11]  查询年龄不在20~23岁之间的学生姓名、系别和年龄
SELECT Sname,Sdept,Sage
FROM     Student
WHERE   Sage NOT BETWEEN 20 AND 23;

#集合确定
[12]查询信息系(IS)、数学系(MA)和计算机科学系(CS)学生的姓名和性别。
SELECT Sname,Ssex
	FROM  Student
	WHERE Sdept IN ( 'IS','MA','CS' );
	
[13]查询既不是信息系、数学系,也不是计算机科学系的学生的姓名和性别
SELECT Sname,Ssex
	FROM  Student
	WHERE Sdept NOT IN ( 'IS','MA','CS' );
	
#字符匹配
匹配串为固定字符串
[14]  查询学号为200215121的学生的详细情况。
SELECT *    
     FROM  Student  
     WHERE  Sno LIKE '200215121';
 [15]  查询所有姓刘学生的姓名、学号和性别
 SELECT Sname ,Sno,Ssex 
 FROM student
 WHERE Sname LIKE '刘%';
 
 [16]  查询姓"欧阳"且全名为三个汉字的学生的姓名。
 SELECT Sname 
 FROM student 
 WHERE Sname like '欧阳_';
 
 [17]  查询名字中第2个字为"阳"字的学生的姓名和学号。
 SELECT Sname,Sno
      FROM Student
      WHERE Sname LIKE '__阳%';
			
[18]  查询所有不姓刘的学生姓名。
SELECT Sname,Sno,Ssex
      FROM Student
      WHERE Sname NOT LIKE '刘%';
			
#3) 使用换码字符将通配符转义为普通字符( ESCAPE '\' 表示“ \” 为换码字符 )
 [19]  查询DB_Design课程的课程号和学分。
SELECT Cno,Ccredit
FROM Course
WHERE Cname LIKE'DB\_Design';

# [例20]  查询以"DB_"开头,且倒数第3个字符为 i的课程的详细情况。
SELECT * FROM Course
WHERE Cname LIKE 'DB\_%i_ _' ;

#关于空值的查询
 [21某些学生选修课程后没有参加考试,所以有选课记录,但没有考试成绩。查询缺少成绩的学生的学号和相应的课程号。
 SELECT Sno,Cno
      FROM  SC
      WHERE  Grade IS NULL;
			
[22]  查所有有成绩的学生学号和课程号。
SELECT Sno,Cno
      FROM  SC
      WHERE  Grade IS NOT NULL;
			
[23]  查询计算机系年龄在20岁以下的学生姓名。
SELECT Sname
       FROM  Student
       WHERE Sdept= 'CS' AND Sage<20;

[12]  查询信息系(IS)、数学系(MA)和计算机科学系(CS)学生的姓名和性别。(变)
SELECT Sname,Ssex
FROM   Student
WHERE  Sdept= ' IS ' OR Sdept= ' MA' OR Sdept= ' CS ';

[10]  查询年龄在20~23岁(包括20岁和23岁)之间的学生的姓名、系别和年龄。(变)
SELECT Sname,Sdept,Sage
FROM Student
     WHERE  Sage>=20 AND Sage<=23;

(3)order by 子句

 这类题型对于解决排名问题有很有帮助的。

#ORDER BY子句
[24]  查询选修了3号课程的学生的学号及其成绩,查询结果按分数降序排列。
SELECT Sno,Grade
        FROM  SC
        WHERE  Cno= ' 3 '
        ORDER BY Grade DESC;
				
[例25]  查询全体学生情况,查询结果按所在系的系号升序排列,同一系中的学生按年龄降序排列。
SELECT  *
        FROM  Student
        ORDER BY Sdept,Sage DESC;

(4)聚集函数

 笔者认为有一定的统计作用。

 [26]  查询学生总人数。
	SELECT COUNT(*)
    FROM  Student;
		
	[27]  查询选修了课程的学生人数。
	SELECT COUNT(DISTINCT Sno)
     FROM SC;
		 
  [28]  计算1号课程的学生平均成绩。
	SELECT AVG(Grade)
          FROM SC
          WHERE Cno= ' 1 ';
					
	   [29]  查询选修1号课程的学生最高分数。
	 SELECT MAX(Grade)
   FROM SC
   WHERE Cno= ' 1 ';
	 

(5)Group by 子句

 SQL查询将Group by子句与聚集函数综合利用可进一步解决更多地问题。

[31]  求各个课程号及相应的选课人数。
 SELECT Cno,COUNT(Sno)
     FROM    SC
     GROUP BY Cno;32] 查询选修了3门以上课程的学生学号
 SELECT Sno
     FROM  SC
     GROUP BY Sno
     HAVING  COUNT(*) >3;

小结

 对于用惯了python的笔者而言,觉得MySQL的语言编辑还是比较友好的,比如代码自动补全、大小写友好、不用考虑python需要考虑的排版问题。另外笔者使用的使用的为Navicat 12 for MySQL企业版本的查询环境。不同版本在个别例题的实现上可能会有细微的不同,需要读者自己注意。文章不足之处望多加指针。

一段

 话说一贵妇最近老是犯偏头疼的毛病,找了许多医生诊治,都未能见效,这天,朋友介绍她去找一位著名的医生,据说其专治各种疑难杂症。贵妇抱着试一试的态度,来到这位医生的诊所诊治,说完自己的病况,医生说:“害!小病嘛,我按着我的法子来,当天就见效,你只要每天早晨起床双手按着自己的太阳穴时对着镜子说:“我不会头疼,我不会头疼, 坚持一段时间后,就好的。”说完后,就让贵妇回家。一些日子后,贵妇和她丈夫送来一面锦旗向医生道谢,贵妇:“医生医术高超,实在感谢您,特送锦旗向您道谢。”医生:“害!应该的应该的嘛。“贵妇偷偷想医生道:”医生啊,您能帮看看我老公的毛病嘛?’他最近一段日子总是不举“医生:”简单,不过您要先出去避让一下才好,我好和您丈夫道明解决之道啊。“贵妇:”害!理解理解,我这就出去您慢慢和我老公说。事成之后我必重谢!“
 你还别说,贵妇丈夫经过那名神医诊治后啊,没过多久就恢复了往日的雄风,而且是有过之而不及啊。于是贵妇准备一份大礼赠送与那名神医。不过,贵妇发现,在睡前,老公总是偷偷在镜子面前出双手按着太阳穴说些什么话。 一日,贵妇好奇心上头,便去偷看监听:只见贵妇老公双手按着太阳穴对着镜子说,她不是我老婆,她不是我老婆。 ……

发布了38 篇原创文章 · 获赞 87 · 访问量 5万+

猜你喜欢

转载自blog.csdn.net/Zengmeng1998/article/details/105282752