分享

PHP教程(11)分组统计+链接查询+子查询+自然查询+视图(增删改查)

 知识书馆 2022-07-17 发布于广东

回顾

列属性:注释和唯一键

关系:一对一,多对一,多对多

范式:规范数据表设计的方式

外键:外键约束(严格,置空,级联)

高级数据操作:增删改查


查询操作

完整语法

select select选项 表达式 from子句 where子句 group by子句 having子句 order by子句 limit子句

group by分组

分组语法

group by就是根据某个条件对数据进行分组。

语法:group by 字段

分组之后,会对数据进行取第一条。

分组主要是用来进行数据统计。

统计函数

(分组统计函数)

         max:求最大值

         min:最小值

         avg:平均值

         count:总记录数,如果使用count(*)那么是统计记录数,如果count(字段)其实也是统计记录数,如果改字段某个值为null,那么不统计。

         sum:求和

count不统计为空的字段(以字段为统计单位)

分组统计原理

group_concat:将分组统计中的某个字段的所有数据进行连接操作

多字段分组

group by字段1,字段2….

分组排序

语法:group by 字段 [asc|desc]

回溯统计

注:能理解就去花时间

系统根据分组的情况,逐层向上回溯,最终直到顶层。

语法:在所有的分组字段之后使用 with rollup;

having子句

having子句与where子句一样,都是用于条件判断的。

区别1

where是判断数据从磁盘读入内存的时候

having是判断分组统计之前的所有条件

区别原理

区别2

having子句中可以使用字段别名,而where不能使用

区别3

having能够使用统计函数,但是where不能使用

order by子句

排序子句,对对应的字段进行排序。排序依赖校对集。

语法

order by 字段 [asc|desc];

多字段排序

order by 字段 [asc|desc],字段2 [asc|desc];

limit子句

limit的基本使用用于限制数据的访问量。

limit标准使用语法

limit  offset,length;

从指定位置(offset)开始,获取对应长度(length)条记录

limit的应用:分页

分页必须知道的条件:页码,每页显示的数据长度

         length:长度

         offset:(页码 – 1 * length

联合查询

联合查询:将多个查询的结果,进行纵向的联合,而不改变字段数,只改变记录数。

语法

select 语句

         union union选项

select 语句

union选项:与select选项完全一致,union选项默认的是distinct(去重)

注意

1.      union使用的时候,必须保证多条查询语句之间的字段数要求一致

2.      union使用的时候,没有数据的类型的概念,只有列数相同的概念。

union意义

1.      合并不同表的数据(数据量太大,导致一张表存不下),往往是用于数据的统计

2.      对同一张表进行数据的不同形式的展示。

需求:将学生表中1班的学生按照年龄升序排序,2班的学生按照年龄降序排序

order by使用

(select 语句 order by子句)

union

(select 语句 order by 子句);

union中使用order by必须搭配limit

(select 语句 order by子句 limit子句)

union

(select 语句 order by 子句 limit子句);

需求:

1.      获取1班的所有学生

select * from student where c_id = 1;

2.      获取1班的所有学生,还要获取对应的班级信息

连接查询

连接查询:将两个表中的数据,进行字段上的拼接,字段数一定会增加。

连接查询分为几类:内连接,外连接,交叉连接,自然连接

连接关键字:join

左表:join关键字左边的表是左表

右表:join关键字右边的表是右表

交叉连接

select * from 1,2;

交叉连接:cross join

交叉连接得到的结果是笛卡尔积,所以应该尽量避免笛卡尔积出现。

内连接

内连接:左表中出现的数据,在右表中也同样存在,那么记录保存,如果不存在就不需要该记录。

语法:

l_table [inner] join r_table on 连接条件

没有连接条件的内连接

内连接

内连接原理

内连接的条件匹配可以使用whereon可以用where代替

外连接

外连接:以某一张表为主表,拿着表中的所有记录去另外的一张表中匹配,如果匹配成功,保留全部记录,如果匹配失败,那么未匹配成功的字段全部置空。

语法:

左(外)连接:左表为主表,右表为副表,l_table left [out] join r_table on 连接条件

右(外)连接:右表为主表,左表为副表,l_table right [out] join r_table on 连接条件

左连接

右连接

左连接转右连接

需求:获取学生以及对应的班级信息,要求只获取1班的所有的学生

自然连接

自然连接:在连接表的时候,不需要指定连接条件,系统自动匹配。

自然连接包括:自然内连接,自然外连接

语法:

l_table natural [left/right] join r_table;

自然内连接

修改student表的name字段之后

自然连接在匹配之后,只会保留一个同名字段(保留的是左表)

自然外连接

内连接和外连接模拟自然连接:使用同名字段作为连接条件,并且合并同名字段。

语法:using(字段列表)

内连接模拟

外连接模拟

using模拟多字段自然连接

注意:实际项目开发中,需求上的满足通常是使用内连接和外连接,很少使用自然连接和交叉连接。

多表连接:与两张表完全一样

A join B on A.字段 = B.字段 join C on A.字段 = C.字段

需求:

1.      查出所有1班的学生;

select * from student where c_id =1;

2.      查出所有PHP141115班的学生

解决方案1select * from student s left join class c on s.c_id = c.id where c.name = 'PHP141115’;

解决方案2

         找出php141115对应的班级idselect id from class where name = 'PHP141115’;

         通过id找出所有该班级学生:select * from student where id = ?;

子查询

一条查询语句出现在另外一条查询语句的内部,这条语句就被称之为子查询语句。

子查询分类

子查询可以根据子查询返回的结果以及子查询出现的位置两种方式进行分类

按结果分类:

         标量子查询:子查询返回的结果是一行一列,一个字段的某一个值

         列子查询:子查询返回的结果是一列,多行,一个字段有多个值

         行子查询:子查询返回的结果是一行多列,多行多列

         表子查询:子查询返回的结果多行多列

按照位置分类:

         where子查询:子查询出现在where条件之后

         from子查询:子查询出现在from之后

         exists子查询:出现在exists之后,exists出现在where之后

标量子查询

子查询返回的结果是一个标量

列子查询

子查询返回的结果是一列。

需求:获取所有班级的所有学生,学生必须在班级中存在。

select * from student where c_id is not null; -- 无法解决

解决方案

1.      获取所有的现有班级的idselect id from class;

2.      从学生表中查出所有数据,判断学生的班级id是否在刚查出来的班级id中存在

集合判断条件(理解性知识)

集合(1,2,3,4,5

any:任意一个,1 = any(集合),只要结果在集合中出现过,就返回true

all:全部,必须满足全部条件才返回真

some:等于其中的一部分,与any完全一致

行子查询

子查询返回的结果是一行多列

需求:找出所有班级中年龄最大,同时身高最高的学生;

行子查询必须构建行元素:有多个字段的元素

select * from 表名 where (字段1,字段2…) =/in (select 字段1,字段2… from 表名);

表子查询

表子查询从返回结果的层面上讲与行子查询完全一样。因为其出现的位置不是在where之后,而是在where之前,from之后。from后接数据源。

需求:求出每个班中身高最高的1个学生。

表子查询出现的原因:因为某些时候,希望order bygroup by之前先执行。

视图

视图:视图是一张虚拟表,存在表结构,但是没有数据。

视图关键字:view

创建视图

语法:

create view 视图名字 as select语句;

视图创建之后发生了什么?

1.      创建视图结构(虚拟表)

2.      在数据库对应的文件夹下创建结构文件

视图是虚拟表,只有结构,没有数据。

视图查看

1.      视图可以像表一样的查看

show tables/show create table/desc 视图名

2.      可以通过视图查看创建语句的方法

show create view 视图名;

3.      查看视图数据:与查看表完全一致

视图不保存数据:数据的来源指的是当视图被调用的时候,系统会自动调用视图的创建语句中的select语句去执行。

修改视图

视图修改的本质是修改视图的数据来源。

语法

alter view 视图名字 as select语句;

删除视图

语法

drop view 视图名字;

视图作用

1.      节省查询语句的长度

2.      对外提供访问接口

保证数据表(基表)的数据安全性。

视图能够选择性的从基表获取数据,并提供给外部。

3.      对外友好性

视图能够对外提供不同的数据信息。(不同的接口定义不同的视图)

视图数据增删改

视图可以为基表进行数据的增删改操作,必须满足以下条件

视图新增数据

1.      视图的数据来源(基表)只能有一个

多表视图不能插入数据

2.      视图中的所有字段,必须包含了基表中不为空或者没有默认值的全部字段。

更新数据:基本没有限制

单表视图更新

多表视图更新

删除数据:与插入数据条件一致,只有单表视图可以删除,多表不能删除

单表视图删除

多表视图删除

视图算法

视图在执行的过程中(视图被查询),到底是如何去执行视图对应的查询语句。

视图算法分为三种:

         合并:merged,先将视图的SQL查询与与外部的查询语句进行语法合并

         临时表:temptable,先执行视图里面的查询语句,结果变成一个临时表

         未定义:undefined,系统自己判断到底使用合并还是临时表,默认的

算法指定语法

create view algorithm = 算法 视图名字 as select语句

    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多