vlambda博客
学习文章列表

Mysql基础专题08-数据库的查询操作

在数据库学习的开篇就提到过,数据的查询操作占数据库操作的99%,也就是说数据的查询操作是重中之重。

查询子句

查询完整语法如下:

select [select选项] 字段列表[字段别名]/* from 数据源 [where子句] [group by子句] [having 子句] [order by 子句] [limit 子句];

select子句

select子句限定了查询结果的处理方式。

语法一、查询所有数据

-- 方式一、查询所有数据select * from 表名称;-- 方式二、查询所有数据select all * from 表名称;

语法二、指定字段别名

-- 查询部分字段的所有数据,并指定别名select 字段名称 [as'别名', ... from 表名称;

语法三、使用distinct去重,distinct关键字必须位于所有字段的前面,且作用于其后所有字段,也就是说只有当distinct关键字后的所有字段重复,才会被去重。

-- 整条记录去重select distinct * from 表名称;-- 部分字段去重select distinct 字段1,字段2,... from  表名称;

from子句

from子句中指定的是数据的来源,有两个来源:数据表和查询语句,而对于数据表的指定可以是单表也可以是多表,如果是多表则每张表之间用","分隔。

语法一、指定单表数据源

select * from 表名称;

语法二、指定多表数据源

select * from 表名称1,表名称2,...; --理论上可以添加多个

当存在多表数据源查询时会产生笛卡尔积,会极大的影响查询性能,所以要尽量避免多表查询。

语法三、指定查询语句为数据源

select * from (select * from 表名称) 别名;

where子句

where子句的作用是筛选数据,主要通过关系运算符和逻辑运算符组成的表达式结果作为条件进行筛选。where子句也是唯一一个直接从磁盘获取数据的时候就开始判断的条件,判断的结果如果成立保存到内存,如果失败直接放弃。

关系运算符:>,<,=,>=,<=,like,between and,in /not in逻辑运算符:&&(and),||(or),!(not)

需要注意的是between本身是闭区间且左边的值必须小于等于右边的值。

栗子,找出年龄大于13小于20学生

select * from student where age between 13 and 20;

group by子句

group by子句的作用是根据某个字段进行分组,语法:group by 字段名称 [asc|desc]。一旦涉及到分组,就不可避免要使用到统计函数,SQL提供了一系列的统计函数:

count():统计分组后的记录数,每一组有多少记录;max():统计每组中的最大值;min():统计每组中的最小值;avg():统计平均值;sum():统计求和;count()函数:参数为*:代表统计记录;参数为字段名:统计对应字段, 如果字段值为null则不参与统计。

技术要点:

1、使用group by 子句时,查询结果会默认根据分组字段进行排序,默认升序,如果使用 group by  字段名称 desc 就是降序。

2、可以使用group by子句进行多字段分组,例如:group by 字段1,字段2,...,分组结果为将多个分组字段对应记录值相同的分为一组。

3、在使用group by子句时,还可以使用group_concat(字段)函数,对分组结果中的某个字段进行拼接。

栗子,以学生表中的性别字段进行分组,并将每组的id进行拼接显示

select sex, group_concat(id) g_ids,count(*) cnt from student group by sex;

执行结果

having子句

having子句和where子句一样都是对结果进行条件筛选,但不同的是筛序时机。where子句从磁盘中获取数据时就已经完成了筛选,而having子句用于分组结果数据的筛序,是在内存中进行的,而且having子句可以使用统计函数、字段别名进行筛序,where却不可以。

栗子,筛选出学生表按性别分组之后,组人数大于5的组。

select sex, group_concat(id) g_ids,count(*) cnt from student group by sex having cnt > 5;

执行结果

Mysql基础专题08-数据库的查询操作

order by子句

order by子句的作用是根据相应的字段进行排序,可以依赖一个字段进行排序,也可以依赖多个字段进行排序,默认升序。

语法:order by 字段1名称 [asc|desc],字段1名称 [asc|desc],...

栗子,根据查询学生信息,age升序,id降序

select * from student order by age asc,id desc;

执行结果

Mysql基础专题08-数据库的查询操作

通过执行结果可以看出,当使用多字段排序时,排序规则为:先根据第一字段排序,如果第一字段值相同时再根据第二字段进行排序,以此类推。

limit子句

limit子句的作用是限制查询的数量,两种限制方式:

直接限制查询数量:limit 记录数;

分页显示查询数据:limit 起始位置 每页显示长度

栗子,两种方式使用limit

-- 查询所有学生数据,只显示前两条select * from student limit 2;-- 查询所有学生数据, 分页显示,每页显示四条,当前显示第二页数据select * from student limit 4,2;

执行结果

Mysql基础专题08-数据库的查询操作

查询方式

常见的查询方式有连接查询、联合查询和子查询,其中连接查询又分为:交叉连接、内连接、外连接(左连接、右连接)和自然连接(内连接、外连接)查询;而子查询根据其语句所在sql中的位置又分为:select子查询、from子查询、where子查询、exists子查询。

连接查询

语法一、交叉连接查询基本语法

select * from 左表 cross join 右表;

交叉连接的查询结果与from 左表,右表的查询结果一致,会产生笛卡尔积, 开发中基本不会使用。它的查询方式就是将左表中的记录逐一和右表中的记录进行拼接,并保留所有拼接记录作为查询结果。

语法二、内连接查询基本语法

select * from 左表 inner join 右表 on 左表.字段 = 右表.字段;

内连接的查询方式是从左表中取出每一条记录, 和右表中所有的记录进行匹配,如果满足on之后的表达式,则保留结果,否则不保留。

语法三、左连接查询基本语法

select * from 左表 left join 右表 on 左表.字段 = 右表.字段;

左连接的查询方式是,以左表为主,从左表中取出每一条记录, 和右表中所有的记录进行匹配,如果满足on之后的表达式,则保留结果,否则只保留左表记录,右表对应字段全部置空。

语法四、右连接查询基本语法

select * from 左表 right join 右表 on 左表.字段 = 右表.字段;

右连接的查询方式是,以右表为主,从右表中取出每一条记录, 和左表中所有的记录进行匹配,如果满足on之后的表达式,则保留结果,否则只保留右表记录,左表对应字段全部置空。

语法五、自然内连接查询基本语法

select * from 左表 natural join 右表;

自然内连接的查询方式和内连接的查询方式原理相同,不同的是自然内连接没有on表达式,它是根据两张表中的同名字段作为连接条件的,如果没有同名字段则会产生笛卡尔积,如果有多个同名字段则以与的关系进行匹配,而且自然内连接会将两张表中的同名字段进行合并,这种不同点在自然左、自然右连接中也是一样的。

语法六、自然左连接查询基本语法

select * from 左表 natural left join 右表

语法七、自然右连接查询基本语法

select * from 左表 natural right join 右表;

联合查询

联合查询是指将多次查询的结果进行拼接,拼接时只关注字段数量,不关注字段类型。

语法

-- 查询语句一union [all(保留所有结果)|distinct(默认,去重)]-- 查询语句二

栗子

select id,name from studentunion allselect * from class;

执行结果

Mysql基础专题08-数据库的查询操作

由执行结果可以看出联合查询确实只关注字段数量,不关注字段类型,如果被联合的两条查询语句产生的结果字段数不一致则联合查询失败。

子查询

子查询是一种比较复杂查询方式,它的产生的结果集是依赖一个或者多个查询语句的结果,也可称之为嵌套查询。

栗子,select子查询,将学生记录中的class_id一列翻译成class_name

select s.id,s.name,s.age,s.sex,(select c.class_name from class c where c.id = s.class_id) as class_name from student s;

栗子,where子查询,查询年龄小于平均年龄的学生

select * from student where age < ( select avg(age) from student);

栗子,from子查询,根据性别分组并查询平均年龄大于10岁的组信息

 select * from  (select sex, avg(age) avg_age from student group by sex) temp where temp.avg_age > 10;

栗子,exists子查询,如果学生表中的班级id在班级表中存在就返回这条记录

select * from student s where exists (select * from class c where c.id = s.class_id);

至此关于数据库的查询操作就介绍完了,下篇来看Mysql中视图的运用。


关注我↓↓↓

您的关注是对我最大的鼓励!

逛逛我的星球呗↓↓↓