欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 财经 > 金融 > 【MySQL】表的CRUD

【MySQL】表的CRUD

2025/4/29 1:34:27 来源:https://blog.csdn.net/2303_80828380/article/details/147480396  浏览:    关键词:【MySQL】表的CRUD

目录

一、Create:

单行插入:

多行插入:

插入否则更新:

插入否则替换:

二、Retrieve:

select查询:

全列查询:

指定列查询:

as重命名:

对查询结果去重:

where条件:

比较运算符:

逻辑运算符:

where语句使用案例:

查询结果进行排序(order by):

筛选分页结果

三、Update:

四、Delete:

删除表中数据:

截断表:

五、对表进行去重操作:

六、聚合函数:

七、分组查询:

having和where的区别:


什么是CRUD呢?

CRUD : Create(创建), Retrieve(读取),Update(更新),Delete(删除)

一、Create:

首先,我们创建一张学生表,然后进行测试

mysql> create table student(-> id int unsigned primary key auto_increment,-> name varchar(20),-> QQ int unsigned unique,-> sex enum('男','女')-> );

单行插入:

单行插入在前面章节我们已经使用过很多次了,这里做下总结:

insert into 表名称(列属性, 不添加默认为全列插入) values (数据);

多行插入:

如果想插入多行,像上面那样一行一行插入比较麻烦,可以在values的后面进行逗号分割开()即可

插入否则更新:

如上,我们的表中是存在主键和唯一键的,所以在插入的时候,如果冲突了就会插入失败

主键冲突:

唯一键冲突:

我们可以在最后加上:

on duplicate key update XX=XXX ...;

其意思就是,首先插入,如果发现插入失败,就更新数据为后面的

  • 0 row affected: 表中有冲突数据,但冲突数据的值和 update 的值相等
  • 1 row affected: 表中没有冲突数据,数据被插入
  • 2 row affected: 表中有冲突数据,并且数据已经被更新

可以使用库函数来进行查看上一次影响了多少行

插入否则替换:

除了insert可以插入数据,还有replace也可以插入数据,replace与insert不同的是

  • 主键 或者 唯一键 没有冲突,则直接插入;
  • 主键 或者 唯一键 如果冲突,则删除后再插入

  • 两行被影响:证明此时主键或者唯一键发生冲突,原数据被删除,然后插入新数据
  • 一行被影响:证明此时主键或者唯一键未发生冲突,正常插入数据

二、Retrieve:

关于查询读取,我们首先创建一个表

mysql> create table Retrieve_test(-> id int unsigned primary key auto_increment,-> name varchar(20) not null,-> chinese float default 0,-> math float default 0,-> english float default 0-> );

接着插入几列数据,来为后来的查询做好准备

select查询:

select是查询后面表达式的值:

所以,我们查询表中的数据,可以用select查询

select 列名(可以是*也就是全部查询,也可以是多列,中间用逗号隔开) from 表名;

全列查询:

用*表示全部,这样就能够查询整张表了

但是一般不建议使用这个,因为可能会使其查询的数据量很大,影响索引的使用

指定列查询:

比如说我要查每一个人的数学成绩:

select name,math from Retrieve_test;

并且这里是按照自己所选择的顺序来的,也可以查询字段相加的值,比如说查询总分的和:

select name,math+chinese+english from Retrieve_test;

as重命名:

对于那些所查询的字段,可以进行as 重命名:

比如将math+chinese+english重命名为total:

语法就是直接在待重命名的数字后面加上as 修改后的名称(as也可以省略)

对查询结果去重:

这里采用关键字distinct,将distinct紧跟在select后面即可:

select distinct 列名 from 表名;

如上,查询每个人的语文成绩,并对结果去重,

where条件:

比较运算符:

运算符/关键字描述示例/注意事项
>>=<<=大于、大于等于、小于、小于等于直接比较数值、日期或字符串
=等于,NULL 不安全NULL = NULL 返回 NULL(非 TRUE
<=>等于,NULL 安全NULL <=> NULL 返回 TRUE(1)
!=<>不等于两种写法功能相同,如 5 != 3 返回 TRUE
BETWEEN a0 AND a1范围匹配(闭区间 [a0, a1]value BETWEEN 10 AND 20 等价于 10 <= value <= 20
IN (option, ...)判断是否属于指定列表中的任意一个值value IN (1, 3, 5) 等价于 value = 1 OR value = 3 OR value = 5
IS NULL判断是否为 NULL仅用于 NULL 检查,如 col IS NULL
IS NOT NULL判断是否不为 NULL如 col IS NOT NULL
LIKE模糊匹配(% 匹配任意多个字符,_ 匹配单个字符)'abc%' 匹配以 abc 开头的字符串;'a_c' 匹配如 a1cadc 等

逻辑运算符:

运算符/关键字描述示例/注意事项
AND多个条件必须都为 TRUE(1),结果才是 TRUE(1)条件1 AND 条件2,若任一条件为 FALSE(0) 或 NULL,结果可能为 FALSE(0) 或 NULL
OR任意一个条件为 TRUE(1),结果为 TRUE(1)条件1 OR 条件2,若任一条件为 TRUE(1),结果即为 TRUE(1)(忽略其他条件是否为 NULL
NOT将条件的逻辑结果取反NOT 条件,若条件为 TRUE(1),结果为 FALSE(0);若为 FALSE(0),结果为 TRUE(1)

where语句使用案例:

使用where语句的时候,是跟在表名后面的

查询英语120~140之间的人

除了使用大于小于符号,还可以使用between and

查询英语成绩90或者150的人

这里可以使用等号+or,也可以使用in (),后者优雅点感觉

查询姓孙的同学或者查询孙某同学

这里采用模糊匹配,为了方便观察,我们在插入孙权进去,接着查看的时候就会发现二者的不一样

查询总分在350以上的,并且将计算式子重命名为总分

但是要注意,在where中是不能使用重命名后的值的,因为条件筛选(where)执行顺序是在select 之前,所以在where的时候还看不知道as total

查询结果进行排序(order by):

ASC 为升序(从小到大),DESC 为降序(从大到小),默认为 ASC

select 字段名 from 表名 order by 待比较字段 desc/asc; //desc为降序排序, asc为升序

查询数学成绩从高到低:

查询各科成绩,按照语文成绩大小排名,如果语文成绩相等就按照数学成绩排名,如果数学成绩相等就按照英语成绩排名

select name,chinese,math,english from Retrieve_test order by chinese desc,math desc,english desc;

按照总分排名:

select name,chinese+math+english as 总分 from Retrieve_test order by 总分 desc;

这里重要的是为什么在order by后面可以使用重命名后的名字呢?但是where却不可以?

因为order by是对数据进行排序的,所以在这之前要先有数据,所以这个是在靠后的

where是对数据进行筛选,这个是先对数据进行筛选后,才会有数据

所以:

对于一套select语句来说:一定是from第一,where第二,select第三,order by第四

筛选分页结果

数据库是会很大的,那么想要提高效率查看是可以进行分页查询,这里采用limit

如果limit后面跟1个数字为N,那么就是从第一行往下数N行显示出来:

如果limit后面跟1个数字为N,M,那么就是从第N行(不包括第N行,也可以理解为下标)往下数M行显示出来:

还有一种写法:

select * from exam_result limit N offset M;

这里的意思和上述是一样的,但是这里看着清楚一点,就是从第N行往下数M行显示出来

三、Update:

对查询到的结果进行更新:

update 表名 set 列名 = XXX ... [where ...] [order by ...] [limit ...]

将曹老板的语文成绩改为115

将曹老板的语文成绩改为110,数学成绩改为110

和order by使用:将总成绩倒数后三位的同学的语文成绩加上20分

select name,chinese,chinese+math+english as 总分 from Retrieve_test order by 总分 limit 3;update Retrieve_test set chinese=chinese+20 order by chinese+math+english limit 3;

注意,这里不支持+=操作符

四、Delete:

删除表中数据:

delete from 表名 [where] [order by] [limit];

在使用的时候最好配合where筛选,不然一不小心就将所有数据删除了

将孙权的成绩删除

当进行删除后,auto_increment是不会受影响的,刚刚删除了8,下一次增加不是8,而是9

截断表:

truncate 表名;

首先创建一张表

接着向这张表中insert数据

此时表中数据如下:

此时进行截断表:

截断表后进行查找数据发现为空,并且发现会将auto_increment清空

五、对表进行去重操作:

这里的去重和之前的去重是不一样的,这里是直接对表进行操作,使去重后的表没有重复的数据,之前的去重是在查询的时候进行去重的

首先创建一个表:

接着向这个表中插入数据:

insert into test values (111,'张三'),(111,'李四'),(222,'王五'),(222,'赵六'),(222,'小七'),(333,'小八');

然后对这个表进行去重操作:

思路:

  1. 创建一张空表tmp,空表和原表test结构一样
  2. 将原表test的去重后的数据(这里采用select筛选去重)插入到新的空表tmp中
  3. 将原表test重命名为别的表,将去重后插入的空表tmp重命名为原表test即可

首先通过like创建空表tmp

接着进行去重查询:

将去重后的结果插入到新的空表tmp中

接着对原来的test进行重命名

rename table 原来的表名 to 重命名后的表名 

最后将tmp重命名为test

这样就对test表进行去重了

六、聚合函数:

MySQL中存在函数,可以被我们调用,我们可以对一组数据进行聚合统计,对其使用的函数就叫做聚合函数

函数说明参数特性
COUNT([DISTINCT] expr)返回查询数据的数量expr 可为任意类型(包括非数字)- COUNT(*) 统计所有行(含 NULL)- COUNT(expr) 忽略 NULL 值
SUM([DISTINCT] expr)返回查询数据的总和expr 必须为数值类型,否则结果无意义(可能返回 NULL 或报错)
AVG([DISTINCT] expr)返回查询数据的平均值expr 必须为数值类型,否则结果无意义(可能返回 NULL 或报错)
MAX([DISTINCT] expr)返回查询数据的最大值expr 可为数值、字符串、日期等可比较类型- 字符串按字典序比较,日期按时间顺序比较
MIN([DISTINCT] expr)返回查询数据的最小值expr 可为数值、字符串、日期等可比较类型- 字符串按字典序比较,日期按时间顺序比较

示例:

对之前的Retrieve_test表进行使用聚合函数:

count(*)返回其总共有多少行

并且可以加上distinct,返回语文成绩不同的有多少个

并且在聚合函数后面还可以加上where判断

统计英语小于120分的人数:

avg平均聚合函数:

统计总成绩的平均分

查看英语成绩大于120分的同学其英语成绩最小有多少分

七、分组查询:

分组的目的是为了进行分组之后,方便进行聚合统计,这里将分组理解为分表

select column1, column2, ... from table group by column;

接下来对oracle 9i的经典测试表进行测试,来自:

DROP database IF EXISTS `scott`;
CREATE database IF NOT EXISTS `scott` DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;USE `scott`;DROP TABLE IF EXISTS `dept`;
CREATE TABLE `dept` (`deptno` int(2) unsigned zerofill NOT NULL COMMENT ' 部门编号 ',`dname` varchar(14) DEFAULT NULL COMMENT ' 部门名称 ',`loc` varchar(13) DEFAULT NULL COMMENT ' 部门所在地点 ' 
);DROP TABLE IF EXISTS `emp`;
CREATE TABLE `emp` (`empno` int(6) unsigned zerofill NOT NULL COMMENT '雇员编号',`ename` varchar(10) DEFAULT NULL COMMENT '雇员姓名',`job` varchar(9) DEFAULT NULL COMMENT '雇员职位',`mgr` int(4) unsigned zerofill DEFAULT NULL COMMENT '雇员领导编号',`hiredate` datetime DEFAULT NULL COMMENT '雇佣时间',`sal` decimal(7,2) DEFAULT NULL COMMENT '工资月薪',`comm` decimal(7,2) DEFAULT NULL COMMENT '奖金',`deptno` int(2) unsigned zerofill DEFAULT NULL COMMENT '部门编号'
);DROP TABLE IF EXISTS `salgrade`;
CREATE TABLE `salgrade` (`grade` int(11) DEFAULT NULL COMMENT '等级',`losal` int(11) DEFAULT NULL COMMENT '此等级最低工资',`hisal` int(11) DEFAULT NULL COMMENT '此等级最高工资'
);insert into dept (deptno, dname, loc)
values (10, 'ACCOUNTING', 'NEW YORK');
insert into dept (deptno, dname, loc)
values (20, 'RESEARCH', 'DALLAS');
insert into dept (deptno, dname, loc)
values (30, 'SALES', 'CHICAGO');
insert into dept (deptno, dname, loc)
values (40, 'OPERATIONS', 'BOSTON');insert into emp (empno, ename, job, mgr, hiredate, sal, comm, deptno)
values (7369, 'SMITH', 'CLERK', 7902, '1980-12-17', 800, null, 20);insert into emp (empno, ename, job, mgr, hiredate, sal, comm, deptno)
values (7499, 'ALLEN', 'SALESMAN', 7698, '1981-02-20', 1600, 300, 30);insert into emp (empno, ename, job, mgr, hiredate, sal, comm, deptno)
values (7521, 'WARD', 'SALESMAN', 7698, '1981-02-22', 1250, 500, 30);insert into emp (empno, ename, job, mgr, hiredate, sal, comm, deptno)
values (7566, 'JONES', 'MANAGER', 7839, '1981-04-02', 2975, null, 20);insert into emp (empno, ename, job, mgr, hiredate, sal, comm, deptno)
values (7654, 'MARTIN', 'SALESMAN', 7698, '1981-09-28', 1250, 1400, 30);insert into emp (empno, ename, job, mgr, hiredate, sal, comm, deptno)
values (7698, 'BLAKE', 'MANAGER', 7839, '1981-05-01', 2850, null, 30);insert into emp (empno, ename, job, mgr, hiredate, sal, comm, deptno)
values (7782, 'CLARK', 'MANAGER', 7839, '1981-06-09', 2450, null, 10);insert into emp (empno, ename, job, mgr, hiredate, sal, comm, deptno)
values (7788, 'SCOTT', 'ANALYST', 7566, '1987-04-19', 3000, null, 20);insert into emp (empno, ename, job, mgr, hiredate, sal, comm, deptno)
values (7839, 'KING', 'PRESIDENT', null, '1981-11-17', 5000, null, 10);insert into emp (empno, ename, job, mgr, hiredate, sal, comm, deptno)
values (7844, 'TURNER', 'SALESMAN', 7698,'1981-09-08', 1500, 0, 30);insert into emp (empno, ename, job, mgr, hiredate, sal, comm, deptno)
values (7876, 'ADAMS', 'CLERK', 7788, '1987-05-23', 1100, null, 20);insert into emp (empno, ename, job, mgr, hiredate, sal, comm, deptno)
values (7900, 'JAMES', 'CLERK', 7698, '1981-12-03', 950, null, 30);insert into emp (empno, ename, job, mgr, hiredate, sal, comm, deptno)
values (7902, 'FORD', 'ANALYST', 7566, '1981-12-03', 3000, null, 20);insert into emp (empno, ename, job, mgr, hiredate, sal, comm, deptno)
values (7934, 'MILLER', 'CLERK', 7782, '1982-01-23', 1300, null, 10);insert into salgrade (grade, losal, hisal) values (1, 700, 1200);
insert into salgrade (grade, losal, hisal) values (2, 1201, 1400);
insert into salgrade (grade, losal, hisal) values (3, 1401, 2000);
insert into salgrade (grade, losal, hisal) values (4, 2001, 3000);
insert into salgrade (grade, losal, hisal) values (5, 3001, 9999);

这里是创建了三张表,

如下是员工表,分别是empno员工号/ename员工姓名/job工作/mgr上级编号/hiredate受雇日期/sal薪金/comm佣金/deptno所属部门编号

如下是部门表,分别是deptno部门编号,dname部门名称,loc部门所在地

如下是薪资等级:

显示每个部门的平均工资和最高工资:

select max(sal) 最高工资,avg(sal) 平均工资 from emp;

这是对一张表emp显示最高工资和平均工资

在这个基础上对部门进行分组

select deptno,max(sal) 最高工资,avg(sal) 平均工资 from emp group by deptno;

根据部门和工作列出最低薪资和平均薪资

select deptno,job,min(sal) 最高工资,avg(sal) 平均工资 from emp group by deptno,job;

这里如果想看到最高工资是谁,那么就需要加上ename:

此时发现会报错,因为一般来说,只有在Group by后面出现了的,才能在前面显示出现,除了这些还有聚合函数可以显示出现,除此之外,一般不能再select后面跟具体的并不是分组条件的列

显示平均工资低于2000的部门和他的平均工资

首先分组聚合显示所有部门的平均工资:

select deptno,avg(sal) 平均工资 from emp group by deptno;

接着对上述的结果进行筛选,这里使用having而不是where,having对聚合结果进行筛选,其作用时间是在最后的,并且可以使用重命名

having和where的区别:

having和where都能够进行条件筛选,但是二者肯定是会有不同的

就像上述将having换成where就会报错,所以二者肯定是不能相互替换的

二者在应用场景和执行顺序有着显著的区别

核心区别:

WHEREHAVING
执行顺序在数据分组前过滤(先过滤后分组)在数据分组后过滤(先分组后过滤)
适用对象过滤原始表的行(单行数据)过滤分组后的组(聚合结果)
聚合函数不能直接使用聚合函数(如SUMAVG必须使用聚合函数或分组字段

案例:显示平均工资低于2000的部门和他的平均工资,但是Smith不参与统计

select deptno,job,avg(sal) 平均工资 from emp where ename!='SMITH' group by deptno,job having 平均工资<2000;

如下这是执行顺序

where是对具体的任意列进行条件筛选

having是对分组聚合之后的结果进行条件筛选

二者条件筛选的阶段是不同的

总的来说:

WHERE:如果过滤条件不依赖分组或聚合函数,优先用WHERE
HAVING:当过滤条件涉及聚合函数或分组结果时,必须用HAVING

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词