查询数据是整个业务逻辑中使用的最多也是最复杂的!
以前的语法:
select *|字段列表from表名where查询条件
比较完整的语法:
select[select选项]*|字段列表[as字段别名]from数据源[where子句][group by子句][having子句][order by子句][limit子句];
注意:
1,from后面的子句往往称之为:五子查询,也叫作五子句!
2,五子查询的选项都可以没有,但是如果有的话,就必须按顺序写!
select选项
是指系统在查询到数据之后,如何显示结果,有两个值:
all:也是默认值,保留所有的查询的结果
distinct:去重,去掉重复的记录,这里的重复是指查询出来的结果当中,所有的字段都相同(也就是完全一样)
别名:所谓的别名,就是给字段或其他表达式等标识符起一个名字,基本语法是:
字段|表达式|表|子查询结果 [as]别名
这里的as可以省略,但是为增强可读性,一般还是写上!
为什么要有别名?
第一:如果出现多表连接查询的时候,往往不同的表中会有相同的字段名,如果使用同名字段,PHP就不好区分!
应该给重复的字段起一个别名:
第二,通常都要给一个表达式起一个别名,代表该表达式的含义!
第三,在真实的项目中,表名往往都比较长,懒得写!
第四,当数据源是一个子查询的时候,必须给该子查询语句起一个别名
先模拟一下:
数据源:这里的数据源就是指查询的数据的来源,可能是一张表,也可能是多张表,也可能是一个子查询的结果,总之是一个结果集!
比较完整的语法:
select[select选项]*|字段列表[as字段别名]from数据源[where子句][group by子句][having子句][order by子句][limit子句];
但是,一条真实的select语句,有可能连字段都可以没有!
典型的,select语句可以当简单的计算器来使用:
也就是说,MySQL中是sql语句,在执行select操作的时候,可以没有数据源!
但是,理论上来说,一条sql语句就必须从一个数据源中去获得数据!
所以,为了保证sql语句的结构的完整性,在MySQL中执行select语句的时候,如果没有数据源,就使用一个虚拟表!
虚拟表:dual
语法:
where 表达式
功能:
通过限定条件对数据进行筛选,得到想要的结果
流程:
逐一的取出每一条记录,先通过当前记录来计算where后面表达式的值,如果计算的结果为真(非0),就返回该记录,如果计算的结果为假(0),就不返回该记录,相当于对所有的记录做了一次遍历!
思考:如果执行如下的语句,会是什么样结果
所以,where子句往往配合着MySQL运算符一起使用!
加减乘除、求余
关系运算符:=、!= 或 <>、> 、< 、="">=、<>
注意:这里的等号就是一个等号=
between and:范围比较,相当于闭区间!比如between A and B,相当于数学上的[A,B],这里的A不能大于B
in和not in 语法形式:in | not in(集合元素)
作用:判断某个值是否属于某个集合当!
逻辑运算符:&& 或 and、|| 或 or、! 或 not
也称之为分组统计查询语句!
语法形式:group by 字段1,[字段2];
所以,分组之后,只会从每个组内部取出第一条记录,这种查询毫无意义!
因为,分组统计查询的主要作用不是分组,而是统计!或者说分组的目的就是对每个分组进行相关的统计!
此时,就要用到系统中的一些统计函数:
sum():求和,就是将某个分组内个某个字段的值全部相加!
max():求某个组内某个字段的最大值
min():求某个组内某个字段的最小值
avg():求某个组内某个字段的平均值
count():统计某个组内非null记录的个数,通常用count(*)来表示!
在真实的项目中,group by子句往往都是配合着统计函数来一起使用的:
案例:在php_student表中,以home字段进行分组,并求每个分组的个数、年龄总和、平均分!
当然,group by后面还可以有多个字段,称之为多字段分组查询!
其实,就是先根据字段1进行分组,然后再根据字段2进行分组(分组的个数变多了)
一个需要注意的地方:
凡是使用统计函数的sql语句,系统都会默认的进行分组,如果没有group by相当于将整个表分成一组,因为统计函数的对象一定是一个分组
就是在进行分组统计的时候,往往需要做上级统计!
比如:先统计各个班的总人数,然后再计算所有班级的总人数,就得到了一个年级的总人数!
先把每个班的最高分统计一下,然后再把每个班的最高分再取最高分,就得到了一个年级的最高分!
在MySQL中,也支持回溯统计,其实就是在语句的后面加上with rollup
注意:既然group by子句出现在where子句之后,就说明可以先将整个数据源进行一次筛选,然后再对筛选的记录进行分组统计查询!
比较完整的语法:
select[select选项]*|字段列表[as字段别名]from数据源[where子句][group by子句][having子句][order by子句][limit子句];
having子句和where子句一样,也是用来筛选数据的,通常是对group by之后的统计结果再次进行条件判断以得到想要的结果!
如果对上面的数据结果集再次的进行一次筛选,比如,只显示平均分在80分以上的!
那么,having子句和where子句到底有什么区别呢?
二者的比较:
1,如果语句中只有having子句或者where子句,此时,它们的效果相同!
2,二者最本质的区别是:where子句是把磁盘(外存)上的数据筛选到内存中,而having子句是把内存中的数据再次的进行筛选!也就是说,执行到having子句的时候,数据已经在内存中了!
3,where子句不能使用统计函数!而having子句可以!因为只有在内存中的数据才能进行统计(数据的运算)
比较完整的语法:
select[select选项]*|字段列表[as字段别名]from数据源[where子句][group by子句][having子句][order by子句][limit子句];
order by:根据某个字段进行排序,有升序和降序!
语法
order by字段名[asc|desc]
默认值是升序,也就是asc,当然,排序要遵守校对集的规则!
思考:如果此时有两个记录的成绩是一样的,如何排序?
多字段排序:order by字段1[asc|desc],字段2[asc|desc];
规则:先按字段1进行排序,如果字段1相同(无法准确的确定顺序),再按字段2进行排序!并且字段1的排序规则可以和字段2的排序规则不一样,比如:字段1按升序排,字段2按降序拍!
联系客服