增加操作:insert into
一条 insert into 语句可以插入多条记录
insert into insert_student values (11,'Jet Lee','male',23), (34,'Buruce Lee',male',23), (44,'Jacky Chen','male',25), (45,'crystal','famale',26);
insert into 支持判断主键(唯一)是否冲突,从而执行更新
insert into inert_student values (44,'Dragon girl','female',23);
insert into 表名 (字段列表) values (值列表) on duplicate key update 字段=值,字段=值;
insert into insert_student values(44,'Dragon girl','female',23) on duplicate key update stu_name='Dragon girl',gender='female',class_id=23;
注意:update后面没有 set !
insert into 表名 select 语句
insert into insert_student select * from foreign_student;
//插入与表 foreign_student 一样的全部数据
insert into insert_student select null,sut_name,gender,class_id from foreign_student;
//从表 foreign_student 复制部分字段数据
注意:并不是一定要字段数一致才可以完成操作,只要是字段数量与字段类型一致就可以完成插入!
查询 select 的用法:
基本的查询语句的结构:
select 字段表达式列表 [from 子句] [where 子句] [group by 子句] [order by 子句] [limit 子句];
字段表达式:
1:如果为字段名,那么字段名就是一个变量的概念,可以参与运算
select md5(class_id) from insert_student;
因此,可以利用各种运算符,来形成sql中的表达式!
可以是一个列表:
每一个表达式,都可以有一个别名:
select 结果内以表达式本身来命名的!
但是有两个典型的问题:
1:表达式直接做名字不容易识别
2:如果名字冲突,不能区分
select 1+1 as a, now() as b,abs(-10) as c,1+1 as d;
as 关键字可以省略,但不建议省略!
group by 子句,分组查询
对查询结果(已经通过where子句过滤之后的数据),按照某个字段,进行分组。
语法: group by 字段;
在分组的结果中,只会显示组内的头一条记录!因此,通常,分组之后的数据,除了分组的字段外,其他字段的逻辑含义很轻!
select * from select_student where 1 group by class_id;
分组的作用不在查询每个组内的具体数据。而其作用主要是在分组统计上:
此时需要使用统计函数(合计函数)加以配合 !
select count(*),class_id from select_student where 1 group by class_id;
合计函数 count() 可以统计结果中的记录数,但是一旦使用了分组查询,则只会统计组内的数据! count() 函数内可以写字段值,如:count(id);
合计函数有:
count() , sum() , avg() , max() , min(),
group_concat(), //组内连接字符串
只要记录存在,则count() 就会统计到数据,而如果相应的字段为null,则count(字段)不会统计上数据!
select sum(money),gender from select_student group by gender;
//统计各个性别的钱数和
select group_concat(stu_name,'-',gender),class_id from select_student group by class_id;
分组排序:
默认的分组后会按照分组字段对结果进行排序。可以group by子句指定排序的方式(升序ASC与降序DESC)
select group_concat(stu_name),class_id from select_student group by class_id desc;
多字段分组:
select count(*),class_id,gender from select_student group by class_id,gender;
使用逗号分隔开多个分组字段即可!统计时,会按照多个字段的组合分组生成结果!
如果是多字段分组,需要查看每个分组的详细情况:
可以使用关键字 with rollup 来回滚统计
select count(*),class_id,gender from select_student grounp by class_id,gender with rollup;
having子句,条件子句
功能上与where类似,都是条件字句
select * from select_student having money > 2000;
与where主要的区别在于执行时机:
执行时机:
where是开始时,从数据源中检索数据的条件
而having是在筛选,分组之后,在得到的结果中,再次进行筛选的语法
因此,having的结果,一定是where已经过滤的结果
having的作用在于,对结果进行二次处理!
例:找到平均身高高于175cm的班级
select avg(height),class_id from select_student group by class_id;
查询条件是avg(height)之后的结果:
此时,where和group by 已经执行结束!可以使用having进行二次过滤
select avg(height),class_id from select_student where 1 group by class_id having avg(height)>175;
为啥要有having :因为where没有办法与合计函数一起使用!原因在于执行顺序的问题
order by排序子句:
对结果进行排序的语句
order by 字段名 [asc | desc],[字段名 [asc | desc]];
可见,可按照多个字段进行排序
select * from select_student order by class_id desc,height as asc;
原则是,先按照第一个字段进行排序,如果字段值相同则采用第二个字段进行排序,依次类推。
limit子句:
限制结果记录数的子句!
从所有的结果中,选择部分结果的子句!
上面的是记录的位置:可以从某个位置开始,取得多少条!
语法:limit start,size;
//start 起始位置
//size 取得的记录数
select * from select_student 1,3
注意:第二个参数是长度,不是位置!
还有一简写,省略 start 起始位置,表示从第0条记录开始。
select子句的全部子句:
书写顺序:
字段表达式,from子句,where子句,group by 子句,having 子句,order by子句,limit子句
书写顺序与执行顺序几乎是一样的!
执行顺序:
from - where - group by - 字段表达式,合计函数表达式 - having - order by - limit
书写顺序不能错,但是子句几乎都可以省略,省略表示不发生操作!
from子句:
表示查询的来源,就是表!
可以写表名列表,使用逗号分割!
select * from select_student,select_class;
如果此时没有条件,相当于形成了一个笛卡尔积!
笛卡尔积:A集合的每个元素,都与B集合的每个元素之间有个关联!
A表记录所有记录,都与B表的所有记录之间存在关联!
此时结果中会将所有的字段都列出来,包括重名的(如上图中的 id 字段)
可以为相应的字段名起别名:
此时访问到某个字段需要使用 表名.字段名的形式!
select select_student.id as s_id,select_class.* from select_student, select_class;
select select_student.id as s_id,stu_name,gender,class_id,select_class.*from select_student,select_class;
如查多次出现 表名.字段名的情况,可以为表名起别名!
dual的问题:
虚拟表名问题,使语法更加规范而已!
where子句,查询条件子句
where 条件表达式
where找到每条记录并依次执行条件表达式,根据条件结果返回数据!
形成条件表达式的基本要素:数据,(变量),运算符,函数调用!
典型的运算符:
关系:>,<,=,>=,<=,<>,!=
关系运算符 like: 模糊查询
not like : like取反
between 3 and 5 : 在3与5之间 (包含3与5)
in / not in : 在/不在 某个集合之内(有限的元素在一起叫集合)
留心:在做批量操作时,in / not in 的出镜率很高!
null值的判断:不能使用普通的运算符,因为运算的结果都是null,而且不能作为运算条件!
应该使用 is null 或者 is not null 来判断!
函数 isnull() 也可以完成判断
select * from select_student where isnull(class_id);