*查询选项 *别名应用 字段别名 表别名 *数据源 单表数据源 多表数据源 子查询数据源 *where子句 比较运算 逻辑运算 空运算 *group by子句 聚合函数 回溯统计 *having子句 *order by子句 *limit子句 分页制作
查询选项:用于对查询结果进行简单数据筛选
查询选项是在select关键字之后,有两个互斥值 all:默认,表示保留所有记录 distinct:去重,重复的记录(所有字段都重复)
steps 1、查询的结果需要去除重复记录
2、使用distinct查询选项去重(默认就是all保留全部)
eg:查询商品表所有品类的商品信息:重复的商品只保留一次(名字、价格、属性都一致)
create table t_6( id int primary key auto_increment, goods_name varchar(50) not null, goods_price decimal(10,2) default 0.00, goods_color varchar(20), goods_weight int unsigned comment '重量,单位克' )charset utf8; insert into t_6 values(null,'mate10',5499.00,'blue',320), (null,'mate10',5499.00,'gray',320), (null,'nokia3301',1299,'black',420); # 考虑所有字段的去重(不含逻辑主键) select distinct goods_name,goods_price,goods_color,goods_weight from t_6; select goods_name,goods_price,goods_color,goods_weight from t_6; # 保留所有 # 不考虑颜色去重 select distinct goods_name,goods_price,goods_weight from t_6; select all goods_name,goods_price,goods_weight from t_6;字段选择:根据实际需求选择的要获取数据的字段信息
*根据实际需求,明确所需要的字段名字,使用英文逗号,分隔 获取所有字段,使用星号通配所有字段 *字段数据可以不一定是来自数据源(select只要有结果即可) 数据常量:select 1 函数或者变量:select unix_timestamp(),@@version (@@是系统变量的前缀,后面跟变量名)
字段别名:给字段取的临时名字
*字段别名使用as语法实现 字段名 as 别名 字段名 别名 *字段别名的目的通常为了保护数据 字段冲突:多张表同时操作有同名字段(系统默认覆盖),想保留全部 数据安全:对外提供数据不使用真实字段名字
steps 1、明确需要查询的字段信息 全部:* 部分:确定字段列表 2、确定存在数据冲突或者需要数据保护(通常可以理解为对外提供给别的系统访问) 使用别名
eg:查询商品信息
# 全部查询 select * from t_7; # 需求为商品名字和价格 select goods_name,goods_price from t_7; # 别名使用 select goods_name as gn,goods_price gp from t_7; #获取当前时间戳和版本号 select unix_timestamp() as now,@@version as version,@@version;数据源:from关键字之后,数据的来源。只要最终结果是一个二维表,都可以当做数据源
*单表数据源:数据源就是一张表 from 表名 *多表数据源:数据来源是多张表(逗号分隔) from 表名1,表名2,…表名N *子查询数据源:数据来源是一个查询结果 from (select 字段列表 from 表名) as 别名 数据源要求必须是一个表 如果是查询结果必须给起一个表别名 *数据表也可以指定别名 表名 as 别名 表名 别名 eg: 1、单表数据源:最简单的数据源,直接从一个数据表获取
select * from t_27;2、多表数据源:利用一张表的一条数据匹配另外一张表的所有记录,记录结果为:记录数 = 表1记录数 * 表2记录数;字段数 = 表1字段数 + 表2字段数(笛卡尔积)
select * from t_27,t_30;3、子查询数据源:数据来源是一个select对应的查询结果
查询语句需要使用括号包裹 查询结果需要指定别名
select * from (select * from t_27,t_30) t; # 数据有冲突查不出来 select * from (select * from t_27) as t;4、如果有时候名字较长或者使用不方便,可以利用表别名
select * from t_30 as t; select t1.*,t2.stu_name from t_27 as t1,t_30 t2;一般情况下别名设置是为了后续条件中可以直接使用别名 如果多表操作下,可以使用表别名来明确提取表字段
where子句:跟在from数据源之后,对数据进行条件匹配
*where是在磁盘读取后,进入内存之前进行筛选 不符合条件的数据不会进入内存 *where筛选的内容因为还没进入内存,所以数据是没有被加工过的 字段别名不能在where中使用 steps 1、确定要查询的数据需要进行条件筛选
2、使用where进行数据筛选
eg: 1、查询t_9表中学生为lily的成绩信息
select * from t_9 where stu_name = 'Lily';2、因为where是在磁盘取数据时进行条件筛选,此时数据没有进入内存,所以字段别名是无效的
# 错误 select stu_name name,score from t_9 where name = 'Lily';运算符:用于进行运算的符号
*比较运算符 >(大于)、<(小于)、=(等于)、>=(大于等于)、<=(小于等于)、<>(不等于) between A and B:A和B之间(A小于B),包括A和B本身(数值比较) in (数据1,数据2,…数据N):在列举的数据之中 like ‘pattern’:像上面样的,用于字符串比较 :单下划线,匹配对应位置的一个任意字符(ab:ab开头+一个字符,匹配abc, ab1,但不能匹配abcd) %:匹配当前位置(往后)任意数量任意字符(ab%:ab开头+任意数量任意字符,匹配 abc,ab1,abcd) *逻辑运算符 and(逻辑与)、or(逻辑或)、not(逻辑非) *null运算符 is null(为空)、is not null(不为空) steps 1、确定需要使用运算符进行运算
2、根据数据要求使用准确的运算符
eg: 1、成绩不及格的学生信息
# 成绩条件:成绩是数值,又是比大小,可以直接使用比较运算符 select * from t_10 where score < 60;2、成绩在60-90间的学生信息
# 成绩条件:区间60到90,可以有两种解决方案 select * from t_10 where score between 60 and 90; select * from t_10 where score >= 60 and score <= 90;3、没有成绩的学生信息
# 成绩条件:成绩为null,所以不能用比较符号查,只能使用is null实现 select * from t_10 where score is null;group by子句:分组统计,根据某个字段将所有的结果分类,并进行数据统计分析
*分组的目的不是为了显示数据,一定是为了统计数据 *group by子句一定是出现在where子句之后(如果同时存在) *分组统计可以进行统计细分:先分大组,然后大组分小组 分组统计需要使用统计函数 group_concat():将组里的某个字段全部保留 any_value():不属于分组字段的任意一个组里的值 count():求对应分组的记录数量 count(字段名):统计某个字段值的数量(NULL不统计) count():统计整个记录的数量(较多) sum():求对应分组中某个字段是和 max()/min():求对应分组中某个字段的最大/最小值 avg():求对应分组中某个字段的平均值 steps 1、确定要进行数据统计
2、确定统计对象:分组字段(可以多个)
3、确定要统计的数据形式:选择对应统计函数
4、分组统计
eg: 1、创建一张表,存储学生信息
create table t_11( id int primary key auto_increment, name varchar(10) not null, gender enum('男','女','保密'), age tinyint unsigned not null, class_name varchar(10) not null comment '班级名称' )charset utf8; insert into t_11 values(null,'鸣人','男',18,'木叶1班'), (null,'佐助','男',18,'木叶1班'), (null,'佐井','男',19,'木叶2班'), (null,'大蛇丸','男',28,'木叶0班'), (null,'卡卡西','男',29,'木叶0班'), (null,'小樱','女',18,'木叶1班'), (null,'雏田','女',18,'木叶1班'), (null,'我爱罗','男',19,'木叶1班'), (null,'向日葵','女',6,'木叶10班'), (null,'博人','男',8,'木叶10班'), (null,'鼬','男',28,'木叶0班');2、统计每班人数
select count(*),class_name from t_11 group by class_name;3、多分组:统计每个班的男女学生数量
select count(*),class_name,gender from t_11 group by class_name,gender;4、统计每个班里的人数,并记录班级学生的名字
select count(*),group_concat(name),class_name from t_11 group by class_name; select count(*),any_value(name),class_name from t_11 group by class_name;回溯统计:在进行分组时(通常是多分组),每一次结果的回溯都进行一次汇总统计
回溯统计语法:在统计之后使用 with rollup
steps 1、确定要进行分组统计
2、确定是多分组统计
3、需要对每次分组结果进行汇总
4、使用回溯统计
eg:统计每个班男女数量,且要知道总人数
# 只统计每个班的男女同学数量,没有班级汇总 select count(*),class_name,gender,group_concat(name) from t_11 group by class_name,gender; # 汇总统计:回溯 select count(*),class_name,gender,group_concat(name) from t_11 group by class_name,gender with rollup;分组排序:在分组后统计结果时可以根据分组字段进行升序或者降序显示数据
*默认的系统就会自动对分组结果根据分组字段进行升序排序 *可以设定分组结果的排序方式 group by 字段名 [ASC]:升序排序(默认) group by 字段名 DESC:降序排序
steps 1、确定使用分组统计
2、需要对结果进行降序排序(升序不用管)
3、使用分组降序排序
eg:对分组结果女性优先显示:gender改为枚举,男1女2
select count(*),class_name,gender,group_concat(name),any_value(name) from t_11 group by class_name,gender desc;having子句:类似于where子句,是用来进行条件筛选数据的
*having子句本身是针对分组统计结果进行条件筛选的 *having子句必须出现在group by子句之后(如果同时存在) *having针对的数据是在内存里已经加载的数据 *having几乎能做where能做的所有事,但是where却不一定 字段别名(where针对磁盘数据,那时还没有) 统计结果(where在group by之前) 分组统计函数(having通常是针对group by存在的)
steps 1、前面有分组统计
2、需要针对分组统计后的结果进行数据筛选
3、使用having组织条件进行筛选
eg:获取班级人数少于3的班级
select count(*) as `count`,class_name,group_concat(name) from t_11 group by class_name having `count` < 3; select count(*) as `count`,class_name,group_concat(name) from t_11 group by class_name having count(*) < 3; # 多用了一次函数(效率降低) select class_name,group_concat(name) from t_11 group by class_name having count(*) < 3; # 没办法,前面没统计,只能自己统计order by子句:排序,根据某个指定的字段进行升序或者降序排序
*排序的参照物是校对集 *order by子句在having子句字后(如果同时存在) *排序分为升序和降序:默认是升序 order by 字段 [ASC]:升序 order by 字段 DESC:降序 *多字段排序:在根据某个字段排序好后,可以再细分排序
steps 1、确定需要排序的字段
2、确定排序的方式:升序 or 降序
3、使用排序 eg: 单字段排序
select * from t_11 order by age; select * from t_11 order by age asc;多字段排序
select * from t_11 order by gender desc,age; select * from t_11 order by gender desc,age asc;limit子句:限制数据的获取数量(记录数)
*limit子句必须在order by子句之后(如果同时存在) *limit限制数量的方式有两种 limit 数量:限制获取的数量(不保证一定能获取到指定数量) limit 起始位置,数量:限制数据获取的位置以及数量(分页)
steps 1、确定要对记录数进行限制
2、确定限制的方式:限定数量 or 限定位置+限定数量
eg:获取t_11前三条数据
select * from t_11 limit 3;获取t_11第三条以后的三条数据
select * from t_11 limit 3,3; select * from t_11 limit 6,3;1、查询操作是所有操作里使用的最多也是最终的操作
2、查询操作的完整语法
select select选项 字段列表[别名]|* from 数据源[别名] where子句 group by子句 having子句 order by子句 limit 子句;*各个位置的顺序不能调换 *五子句(where、group by、having、order by、limit)可以没有,但是出现后一定要保证顺序 *group by到最后都是针对已经加载到内存中的数据进行加工处理
3、很多结构的组合其实可以达到同一效果,但是可能过程和效率会不同