MySQL表的增删查改

时间:2022-10-05 07:52:56

一、增

首先我们来创建一张表:

mysql> create table students(
    -> id int unsigned primary key auto_increment comment '用户主键',
    -> sn int not null unique key comment'学号',
    -> name varchar(20) not null,
    -> qq varchar(20) unique
    -> );

MySQL表的增删查改

1.单行全列插入

当全列插入的时候,插入哪个位置可以进行省略:

mysql> insert into students (id,sn,name,qq) values(1,1,'张三','255126421');//不省略插入
mysql> insert into students values(2,2,'李四','654321');//不省略插入

MySQL表的增删查改

2.选择列插入

如果是选择列插入,必须要带插入的位置:

mysql> insert into students (sn,name) values(3,'王五');

MySQL表的增删查改

3.一次插多条记录

可以使用逗号隔开,从而实现一次插入多条记录:

mysql> insert into students (sn,name,qq) values(4,'赵六','35667788'),(5,'田七','347763562'),(6,'周八','34262542154');

MySQL表的增删查改

4.冲突则更新

不冲突则插入,由于主键或者唯一键对应的值而导致插入失败,冲突不希望报错,冲突就修改,如果修改的也有问题,则报错。

mysql> insert into students (id,sn,name,qq) values(8,125,'关羽','255126421') on duplicate key update qq='2356555',name='武九';//qq冲突了
mysql> insert into students (id,sn,name,qq) values(8,2,'关羽','255126421') on duplicate key update qq='23565554',name='吕蒙';//与李四sn冲突了

发现是张三的qq和它冲突了,因此将张三更新为武九的内容,但是注意,因为我们只指定了名字和qq,因此主键和学号依然使用的是张三原来的。李四的同理。
MySQL表的增删查改
当和不同行的列冲突的时候:

mysql> insert into students (id,sn,name,qq) values(4,4,'刘备','2356555') on duplicate key update id='8',qq='245254535',name='刘备',sn=10;//与王五的id,赵六的sn,武九的qq冲突

MySQL表的增删查改
此时更新的是最先发生冲突的那一个即王五。

5.替换

没有冲突则插入,有冲突则全部替换

mysql> replace into students (sn,name,qq) values(9,'曹操','56789039');//无冲突插入

MySQL表的增删查改

mysql> replace into students (id,sn,name,qq) values(1,4,'张飞','347763562');//id与武九,sn与赵六,qq与田七冲突

MySQL表的增删查改
此时我们发现这三行都被替换了。replace是强制替换,而on duplicate key update是冲突后将冲突的改成我们指定的一个。

二、查

重新建立一张表:

mysql> create table exam_result(
    -> id int unsigned primary key auto_increment,
    -> name varchar(20) not null comment '同学姓名',
    -> chinese float default 0.0 comment '语文成绩',
    -> math float default 0.0 comment '数学成绩',
    -> english float default 0.0 comment '英语成绩'
    -> );

MySQL表的增删查改
向其中插入一些数据:

mysql> insert into exam_result (name,chinese,math,english) values
    -> ('钢铁侠',67,98,56),
    -> ('美队',87,78,77),
    -> ('雷神',88,98,90),
    -> ('绿巨人',82,84,67),
    -> ('黑寡妇',55,85,45),
    -> ('鹰眼',70,73,78),
    -> ('死侍',75,65,30)
    -> ;

1.查看表中所有数据

mysql> select* from exam_result;

MySQL表的增删查改

2.所有行指定列查询

mysql> select id,name,english from exam_result;//查询所有行以及id,name,english列

MySQL表的增删查改

3.增加表达式列

注意只能是表达式,字符串不行:

mysql> select id,name,english,10+10,english+10 from exam_result;//增加表达式10+10

MySQL表的增删查改
注意,对english+10并不影响表中的数据,可以把查询操作理解成拷贝。
在查询的时候,显示的列名太丑了,我们还可以进行重命名操作,注意其实每一个列都可以当成一个表达式:

mysql> selecct id,name 名字,english 英语成绩,english+math+chinese 总分 from exam_result;

MySQL表的增删查改

4.查询结果去重

mysql> select distinct math from exam_result;//去重数学成绩

MySQL表的增删查改
如果在math后加上id等信息,则这些信息都不一样才会发生去重。

5.条件筛选:where条件

where条件是在select语句执行之前执行的,因为要先进行筛选。

(1)运算符概述

比较运算符:

比较运算符 说明
>,>=,<,<= 大于,大于等于,小于,小于等于
= 等于,NULL不安全,例如NULL=NULL的结果是NULL
<=> 等于,NULL安全,例如NULL<=>NULL的结果就是TRUE(1)
!=,<> 不等于
between a0 and a1 范围匹配,[a0,a1],如果a0<=value<=a1,返回TRUE(1)
in(option,…) 如果是option中的任意一个,返回TRUE(1)
is null 是NULL
is not null 不是NULL
like 模糊匹配。%表示任意多个(包括0个)任意字符,_表示任意一个字符

逻辑运算符:

运算符 说明
and 多个条件必须都为TRUE(1),结果才是TRUE(1)
or 任意一个条件为TRUE(1),结果为TRUE(1)
not 条件为TRUE(1),结果为FALSE(0)

注意,在mysql中,赋值符号和等于符号都是=,没有==符号。

(2)英语成绩小于60的同学

mysql> select id,name,english from exam_result where english<60;

MySQL表的增删查改

(3)语文成绩在[80,90]之间的同学

mysql> select id,name,chinese from exam_result where chinese between 80 and 90;

MySQL表的增删查改

(4)数学成绩是58,59或者98,99的同学

mysql> select id,name,math from exam_result where math=58 or math=59 or math=98 or math=99;//可以使用or相连,但是非常的麻烦
mysql> select id,name,math from exam_result where math in(58,59,98,99);//使用in语句解决这一问题

MySQL表的增删查改

(5)查找姓黑的同学以及查找黑某同学

先插入俩人:

mysql> insert into exam_result  values(8,'黑豹',99,100,100);
mysql> insert into exam_result  values(9,'黑蝠王',99,100,100);
mysql> select id,name from exam_result where name like '黑%';//查找姓黑的同学

MySQL表的增删查改

mysql> select id,name from exam_result where name like '黑_';

MySQL表的增删查改
查找黑某同学,某表示名字是一个字。

(6)总分在200以下的同学

mysql> select id,name,math+chinese+english 总分 from exam_result where math+chinese+english<200;

注意,由于先筛选再重命名,因此where是在select之前就执行了的,where语句是不认识总分这个别名的,因此如果将where语句中的math+chinese+english改成总分会发生报错。
MySQL表的增删查改

(7)语文成绩>80并且不姓黑的同学

mysql> select id,name,chinese from exam_result where chinese>80 and name not like '黑%';//使用and来进行一些复合查询

MySQL表的增删查改

(8)孙某同学,否则总成绩>200

mysql> select id,name,chinese+math+english 总分 from exam_result where name like '黑%' or chinese+math+english>200;

MySQL表的增删查改

6.NULL查询

在进行NULL查询的时候,不建议使用<=>而建议使用is null和is not null。
我们使用students表来举例,可以向其中插入一些空值。

mysql> insert into students (id,sn,name) values(4,4,'吕布');
mysql> insert into students values(3,3,'黄盖');

向其中插入两个值,不指定qq,此时默认为空:
MySQL表的增删查改

mysql> select id,name from students where qq is null;//查询qq是空的人
mysql> select id,name from students where qq is not null;//查询qq不是空的人。

NULL与任何值运算都为NULL,null只和null等价。

mysql> select null<=>null,null<=>0,null<=>'';

MySQL表的增删查改

7.查询结果排序

使用order by语句asc表示升序,desc表示降序。

mysql> select id,name,math from exam_result order by math desc;//数学成绩按降序排序

MySQL表的增删查改
如果有null出现,把null当做最小值。

mysql> select * from exam_result order by math desc,english asc,chinese asc;//按数学降序,英语升序,语文升序显示

MySQL表的增删查改
排序的结果是,按数学降序排序,如果数学成绩相同则再按语文升序排序。

mysql> select id,name,chinese+math+english 总分 from exam_result order by 总分 desc;//按总分排序

MySQL表的增删查改
注意,order就可以使用总分了,因为数据的筛选和求和都由select做完,之后再进行排序,所以order的执行顺序在select之后,它知道总分这个定义。

8.筛选分页结果

MySQL表的增删查改
即找到排名前几的同学:

mysql> select name,english+math+chinese total from exam_result order by total desc limit 3;

筛选总成绩排名前三名的同学:
MySQL表的增删查改
注意,limit关键字永远放在最后面。

mysql> select* from exam_result limit 2,2;//选出表中,从第二行开始的后两行,即第3,4行。

MySQL表的增删查改

mysql> select* from exam_result limit 4 offset 0;//筛选出从0开始偏移量在4之内的所有行

MySQL表的增删查改
通常使用offset的方式进行筛选。

三、改

1.将钢铁侠数学成绩改为80分

update…set用来进行表中数据的更新。更新或者删除之前一定要先做好备份。

mysql> update exam_result set math=80 where name='钢铁侠';

将钢铁侠的数学成绩改为80分。
MySQL表的增删查改

2.将总成绩倒数前三的同学的数学成绩加30分

mysql> update exam_result set math=math+30 order by math+english+chinese asc limit 3;

MySQL表的增删查改
注意,这里没有where子句,但是limit限制了范围。

四、删

1.删除全部数据

delete from exam_result;

2.删除钢铁侠

mysql> delete from exam_result where name='钢铁侠';

MySQL表的增删查改
对表格中数据进行删除一定记得要先备份!!!

3.删除表数据与auto_increment

我们在这里新建立一个表专门来用于删除:

mysql> create table for_delete( id int unsigned primary key auto_increment, name varchar(16) not null );
mysql> insert into for_delete (name) values('a'),('b'),('c');

MySQL表的增删查改
MySQL表的增删查改
然后我们删除这个表中的数据,并重新插入a,b,c

mysql> delete from for_delete;
mysql> insert into for_delete (name) values('a'),('b'),('c');

此时我们会发现auto_increment没有对id进行更新,而是从4开始赋值id:
MySQL表的增删查改

4.截断表

为了避免上述使用delete删除的情况,引入了truncate来进行删除:

mysql> truncate table for_delete;//使用truncate删除
mysql> insert into for_delete (name) values('a'),('b'),('c');//重新插入a,b,c

MySQL表的增删查改
此时可以看到id从1开始赋值了。

五、去重

建立一个表,并向其中插入一些重复性数据:

mysql> create table duplicate_tb(
    -> id int,
    -> name varchar(16)
    -> );
mysql> insert into duplicate_tb (id,name) values(100,'aaa');
mysql> insert into duplicate_tb (id,name) values(100,'aaa');
mysql> insert into duplicate_tb (id,name) values(200,'bbb');
mysql> insert into duplicate_tb (id,name) values(200,'bbb');
mysql> insert into duplicate_tb (id,name) values(200,'bbb');
mysql> insert into duplicate_tb (id,name) values(300,'ccc');

MySQL表的增删查改
创建一个和duplicate_tb属性相同的表,并将duplicate查询去重之后的数据插入该表中:

mysql> create table duplicate_tb_bak like duplicate_tb;
mysql> insert into duplicate_tb_bak select distinct* from duplicate_tb;

MySQL表的增删查改
由于要向duplicate_tb中插入,因此还需要进行重命名操作:

mysql> rename table duplicate_tb to old_duplicate_tb;
mysql> rename table duplicate_tb_bak to duplicate_tb;

六、分组聚合

分组聚合主要使用的是group by和having子句。分组聚合需要注意的是要先进行分组,然后再聚合。这里我们使用了oracle 9i的经典测试表来进行测试:
一共有三张表:
1.EMP:员工表
2.DEPT:部门表
3.SALGRADE:工资等级表
下图是三张表的结构:
MySQL表的增删查改
MySQL表的增删查改

1.显示每一个部门的平均工资与最高工资

首先对部门进行分组,然后再在组内进行聚合:

mysql> select deptno,avg(sal),max(sal) from emp group by deptno;

执行的顺序就是先将部门按组号分组,然后select再在每个组中执行select deptno,avg(sal),max(sal),称该过程为聚合。
MySQL表的增删查改

2.显示每个部门的每种岗位的平均工资和最低工资

mysql> select deptno,job,avg(sal),min(sal) from emp group by deptno,job;

此时以两个标准进行分组,即deptno和job,将deptno相同的排列在一起,对其中的job进行聚合。
MySQL表的增删查改

3.显示平均工资低于2000的部门和它的平均工资

having和group配合使用,可以对group的结果进行过滤:

mysql> select deptno,avg(sal) from emp group by deptno where avg(sal)<2000;//失败
mysql> select deptno,avg(sal) from emp group by deptno having avg(sal)<2000;//成功

MySQL表的增删查改
我们发现where和having都是进行筛选的语句,它们有什么区别呢?
其中where是在整个表格里做筛选的语句,它的执行是在group by之前,而having是在筛选之后执行是在group的后面。
where是过滤表中数据的,而having是过滤分组数据的。在分组之前需要先通过where来拿到所要用到的数据。整体的执行顺序是:where->group by->select聚合->having