增加操作: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);

wKiom1Zan0eSMgObAABUuZOIO4Y072.jpg


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;

wKioL1ZaoP7D01OeAABUuZOIO4Y246.jpg

注意: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 复制部分字段数据

wKiom1ZaolqT0hhmAABYSaRCyHw853.jpg


注意:并不是一定要字段数一致才可以完成操作,只要是字段数量与字段类型一致就可以完成插入!


查询 select 的用法:


基本的查询语句的结构:

    select 字段表达式列表 [from 子句] [where 子句] [group by 子句] [order by 子句] [limit 子句];


字段表达式:

1:如果为字段名,那么字段名就是一个变量的概念,可以参与运算

select md5(class_id) from insert_student;

wKiom1Zapf3z_EXOAAB0OE7UXgE676.jpg


因此,可以利用各种运算符,来形成sql中的表达式!


可以是一个列表:

wKiom1Zap2bQC5rnAAA0a9G_iP8029.jpg

每一个表达式,都可以有一个别名:

    select 结果内以表达式本身来命名的!

wKioL1ZarHmQeEgrAAA6YQz19A4245.jpg


    但是有两个典型的问题:

        1:表达式直接做名字不容易识别

        2:如果名字冲突,不能区分

select 1+1 as a, now() as b,abs(-10) as c,1+1 as d;

wKiom1ZarOWzwoR7AAA3dk8OvmI868.jpg


        as 关键字可以省略,但不建议省略!


group by 子句,分组查询

    对查询结果(已经通过where子句过滤之后的数据),按照某个字段,进行分组。

    语法: group by 字段;

    在分组的结果中,只会显示组内的头一条记录!因此,通常,分组之后的数据,除了分组的字段外,其他字段的逻辑含义很轻!

select * from select_student where 1 group by class_id;

wKiom1ZbBZnRuy2aAAB9f0Nxgmk034.jpg


分组的作用不在查询每个组内的具体数据。而其作用主要是在分组统计上:

此时需要使用统计函数(合计函数)加以配合 !

select count(*),class_id from select_student where 1 group by class_id;

合计函数 count() 可以统计结果中的记录数,但是一旦使用了分组查询,则只会统计组内的数据! count() 函数内可以写字段值,如:count(id);

wKiom1ZbDJ-wqWquAABB8D4MYDk551.jpg


合计函数有:

    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;

wKiom1ZbEySjP0wcAADFy4HOKtM651.jpg



分组排序:

    默认的分组后会按照分组字段对结果进行排序。可以group by子句指定排序的方式(升序ASC与降序DESC)

select group_concat(stu_name),class_id from select_student group by class_id desc;

wKiom1ZbFFrThtQRAABzzrCHq6g346.jpg


多字段分组:

select count(*),class_id,gender from select_student group by class_id,gender;

wKioL1ZbFVqwWq9GAAA-QACBAkQ265.jpg


使用逗号分隔开多个分组字段即可!统计时,会按照多个字段的组合分组生成结果!


如果是多字段分组,需要查看每个分组的详细情况:

    可以使用关键字 with rollup 来回滚统计

select count(*),class_id,gender from select_student grounp by class_id,gender with rollup;

wKioL1ZbF8jiiZiiAACWk1hejwc441.jpg


having子句,条件子句

    功能上与where类似,都是条件字句

select * from select_student having money > 2000;

    与where主要的区别在于执行时机:

wKiom1ZbygGSQ7Z_AABdWhkJwus772.jpg


     执行时机:

        where是开始时,从数据源中检索数据的条件

        而having是在筛选,分组之后,在得到的结果中,再次进行筛选的语法

        因此,having的结果,一定是where已经过滤的结果

wKiom1ZbyvyDmOWtAACQmwI7UDo247.jpg


having的作用在于,对结果进行二次处理!

例:找到平均身高高于175cm的班级

select avg(height),class_id from select_student group by class_id;


wKiom1Zby9zCdsxcAABAUHbF15o867.jpg


查询条件是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;

wKiom1Zbz0rjbboFAABwIsLsDis653.jpg

原则是,先按照第一个字段进行排序,如果字段值相同则采用第二个字段进行排序,依次类推。


limit子句:

    限制结果记录数的子句!

    从所有的结果中,选择部分结果的子句!

wKioL1Zb0RqxAfHEAABvGQcrRAI101.jpg


上面的是记录的位置:可以从某个位置开始,取得多少条!


语法:limit start,size;

            //start 起始位置

            //size  取得的记录数

select * from select_student 1,3


 wKioL1Zb0jzguWEHAAEFSw3ywUk113.jpg


注意:第二个参数是长度,不是位置!

还有一简写,省略 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;

wKioL1ZarkXSENJgAACPRl4taWo010.jpg


如果此时没有条件,相当于形成了一个笛卡尔积!

笛卡尔积:A集合的每个元素,都与B集合的每个元素之间有个关联!

          A表记录所有记录,都与B表的所有记录之间存在关联!

此时结果中会将所有的字段都列出来,包括重名的(如上图中的 id 字段)


可以为相应的字段名起别名:

此时访问到某个字段需要使用 表名.字段名的形式!

select select_student.id as s_id,select_class.* from select_student, select_class;

wKioL1ZasHLBb4-9AAB_gh6fJXI268.jpg

select select_student.id as s_id,stu_name,gender,class_id,select_class.*from select_student,select_class;

如查多次出现 表名.字段名的情况,可以为表名起别名!

wKiom1ZasQLClzd7AACWOB485DY850.jpg


dual的问题:

    虚拟表名问题,使语法更加规范而已!

wKiom1ZasdeBxc2DAAAj-Zw-cP4141.jpg


where子句,查询条件子句

    where 条件表达式

where找到每条记录并依次执行条件表达式,根据条件结果返回数据!

形成条件表达式的基本要素:数据,(变量),运算符,函数调用!

wKiom1Zas76g0vaUAABwwe_OjgA219.jpg

典型的运算符:

    关系:>,<,=,>=,<=,<>,!=

    关系运算符 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);