前面第二篇中,整理并讲解了查询的一般语法及单表查询的常规内容。第三篇数据库设计中讲到,为了最大限度地降低数据冗余(重复),通过建立表与表之间的关联性,也就是主外键关系来实现这一目的。
但带来的问题是,在一定程度上是减少了数据冗余,却也增加了查询的难度,即:需要通过多表关联查询,才能获取到需要的数据。
本文重点梳理高级查询的相关内容,特别是多表查询和子查询,是学习的的重点和难点内容,需要学习者细细体会。
01SQL中的内置函数
前面讲过聚合函数,用来统计数据的一类函数。此外还有字符串函数、日期函数以及数学函数、系统函数等。本文主要讲解字符串、日期函数,另外两类函数大家参考相关资料学习,很容易上手。
字符串函数主要用来处理表格中有关字符串字段相关的操作。包括:获取字符串的长度、去除前后的空格、截止子字符串、替换函数等。
第一行代码可以获取姓名列的长度,即学生姓名中含有多少个字;第二行代码可以将学号转换为大写或小写字母输出;第三行代码通过左右截取函数的嵌套,可以去除姓名列前后的空格。需要注意:查询的结果不会影响原有表格内的数据,只是一张虚拟表格。
第一行代码查询子字符串,获取所有学员的姓氏(不考虑复姓);第二行代码获取所有学员的名字(不含姓氏)。因为学员名字长度不同,先求总长度,减去姓氏的一个字符长度,再右截取不同长度的学员名字;第三行代码将地址列中含有“重庆”的内容替换为“重庆市沙坪坝区”。在使用时,这三个函数除了传入字符串参数外,还传入了其他参数,读者在使用时需明细参数的意义。
in 用法匹配括号里面的,符合就返回结果集中
查询学生表中一共有多少人 查询学生表中id最大的学生
表示查询这一列中的最小值
返回字符串str的最左面len个字符 返回字符串str的最右面len个字符。
注意:分组后分组依据会显示在结果集,其他列不会出现 上面的例子,在统计人数的时候结果集中显示的是count(*)这个有时候我们并不知道他代表的是什么,如何改成有语义的命名 分组后不能使用where做条件过滤,需要一个使用新的having函数 having用在分组之后的条件过滤,两个功能是一样的,只是作用的位置不一样 分页的原因:如果数据量很大的话,一次性将所有数据查询出来,不仅不方便查看而且耗费传输带宽。那么就使用到了分页功能,一次只查询一页的数据,如:
新需求:给students表中的学生分下班,新加一个class_id字段,保存班级id,之前已经有一个class表已经保存了班级信息了,如: id小于15分到1班,大于等于分到2班,如: 内连接查询:查询的结果为两个表匹配到的数据,两个表都能匹配上的数据将返回给结果集 使用内连接查询学生表和班级表
右连接查询:查询的结果为两个表匹配到的数据,右表特有的数据,对于左表中不存在的数据使用null填充 左连接查询:查询的结果为两个表匹配到的数据,左表特有的数据,对于右表中不存在的数据使用null填充 1、查询学生姓名以及对应班级名称
2、查询python1班所有学生的个人信息和班级信息 都是用在子查询里面 用作比较运算
any 表示任意一个 有一个满足了结果就为true 和some是一样的效果 查询出在学生表当中 2班级的学生年龄 都大于1班级的所有同学 查询出在学生表当中 2班级的学生年龄 任意一个大于1班级的所有同学
在一个select语句中嵌入了另外一个select语句,嵌入的这个select语句就是子查询语句。 子查询返回一行一列的数据,称之为标量子查询
–查询学生年龄小于平均年龄的学生信息 子查询返回的是一列多行的数据,称之为列级子查询
备注:可用于子查询的关键字有4个(in、all、any、some) 子查询返回的是一行多列,称之为行级子查询 –查询一班同学中年龄最大的同学信息,单独使用子查询这条语句查的结果可以看出结果集是一行多列。嵌套到主查询后将查出一班同学中年龄最大的同学信息 子查询返回多行多列,称之为表级子查询 查询学生信息对应班级名称,子查询返回的数据充当数据源,再进行过滤。
语句格式:insert into 表名 (列1,列2) select … #这个方法可以将查询的结果直接保存到表里
3、查询名字由4个中文字符的学生学号和姓名(运算 函数) 4、查询名字中有”不“字或“嫣”字的学生的姓名(模糊) 5、查询学生选课的所有日期(去重) 6、查询男学生的姓名和生日按年龄从大到小排列(排序) 7、查询每个学生的学号和平均成绩(分组和聚合函数) 8、查询选了两门以上的课程的学生姓名(子查询/分组条件/集合运算) 9、查询选课学生的姓名和平均成绩(子查询和连接查询) 10、查询每个学生的姓名和选课数量(左外连接和子查询) |