MySQL表的增删改查

目录

  • Create
    • 单行数据 + 全列插入
    • 多行数据 + 指定列插入
    • 插入否则更新
    • 替换
  • Retrieve
  • SELECT 列
    • 全列查询
    • 指定列查询
    • 查询字段为表达式
    • 为查询结果指定别名
    • 结果去重
    • WHERE 条件
    • 结果排序
    • 筛选分页结果
  • Update
    • 将孙悟空同学的数学成绩修改为80分
    • 将曹孟德同学的数学成绩变更为 60 分,语文成绩变更为 70 分
    • 将总成绩倒数前三的 3 位同学的数学成绩加上 30 分
    • 将所有同学的语文成绩更新为原来的 2 倍
  • Delete
    • 删除数据
    • 截断表
  • 插入查询结果
  • 聚合函数
    • 统计班级共有多少同学
    • 统计班级收集的 qq 号有多少
    • 统计本次考试的数学成绩分数个数
    • 统计数学成绩总分
    • 统计平均总分
    • 返回英语最高分
    • 返回 > 70 分以上的数学最低分
  • group by子句的使用
    • 显示每个部门的平均工资和最高工资
    • 显示每个部门的每种岗位的平均工资和最低工资
    • HAVING 条件

表的增删查改简称CRUD:Create(新增),Retrieve(查找),Update(修改),Delete(删除)。
CRUD的操作对象是对表当中的数据,是典型的DML(Data Manipulation Language)数据操作语言。

Create

基本语法:

INSERT [INTO] table_name [(column1 [, column2] ...)] VALUES (value_list1) [, (value_list2)] ...;

参数说明:

  • SQL中大写的表示关键字,[ ]中代表的是可选项。
  • SQL中的每个value_list都表示插入的一条记录,每个value_list都由若干待插入的列值组成。
  • SQL中的column列表,用于指定每个value_list中的各个列值应该插入到表中的哪一列。

下面创建一个学生表,表当中包含自增长的主键id、学号、姓名和QQ号。

MySQL表的增删改查_第1张图片

查看表结构如下:

MySQL表的增删改查_第2张图片

单行数据 + 全列插入

接下来我们使用insert命令向表中插入数据,插入两条记录,value_list 数量必须和定义表的列的数量及顺序一致。注意,这里在插入的时候,也可以不用指定id(当然,那时候就需要明确插入数据到那些列了),那么mysql会使用默认的值进行自增。

MySQL表的增删改查_第3张图片

多行数据 + 指定列插入

insert命令也可以向表中插入多行数据,此时插入的多条记录要使用逗号隔开,同时也可以指定列进行插入。

MySQL表的增删改查_第4张图片

插入否则更新

向表中插入数据会出现由于 主键 或者 唯一键 对应的值已经存在而导致插入失败。

主键冲突

MySQL表的增删改查_第5张图片

唯一键冲突

MySQL表的增删改查_第6张图片

此时可以选择性的进行同步更新操作语法:

  • 如果表中没有冲突数据,则直接插入数据。
  • 如果表中有冲突数据,则将表中的数据进行更新。

基本语法如下:

INSERT ... ON DUPLICATE UPDATE column1=value1 [, column2=value2] ...;

比如向学生表中插入记录时,如果没有出现主键冲突则直接插入记录,如果出现了主键冲突,则将表中冲突记录的学号和姓名进行更新。

MySQL表的增删改查_第7张图片

其中:

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

通过 MySQL 函数我们可以获取受到影响的数据行数。

MySQL表的增删改查_第8张图片

替换

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

此时需要用到的就是我们的 replace SQL语句。

MySQL表的增删改查_第9张图片

其中:

  • 1 row affected: 表中没有冲突数据,数据被插入;
  • 2 row affected: 表中有冲突数据,删除后重新插入。

Retrieve

基本语法:

SELECT [DISTINCT] {* | {column1 [, column2] ...}} FROM table_name [WHERE ...] [ORDER BY ...] [LIMIT ...];

下面创建一个成绩表,表当中包含自增长的主键id、姓名以及该同学的语文成绩、数学成绩和英语成绩。

MySQL表的增删改查_第10张图片

接下来我们向表中插入一部分数据:

MySQL表的增删改查_第11张图片

SELECT 列

全列查询

在前面的使用中我们通常使用*进行全列查询,但是通常情况下不建议进行全列查询,因为:

  • 查询的列越多,意味着需要传输的数据量越大;
  • 可能会影响到索引的使用。

MySQL表的增删改查_第12张图片

指定列查询

指定列的顺序不需要按定义表的顺序来,列与列之间使用逗号隔开就可以了。

MySQL表的增删改查_第13张图片

查询字段为表达式

表达式不包含字段

MySQL表的增删改查_第14张图片

表达式包含一个字段

MySQL表的增删改查_第15张图片

表达式包含多个字段

MySQL表的增删改查_第16张图片

为查询结果指定别名

基本语法:

SELECT column [AS] alias_name [...] FROM table_name;

有的查询结果可能不太能体现我们需要表达的意思,我们可以取别名。

MySQL表的增删改查_第17张图片

结果去重

比如我们在查询成绩时发现有两个人是成绩是重复的,此时我们想要去除重复值,就需要使用到 distinct SQL语句。

MySQL表的增删改查_第18张图片

WHERE 条件

添加where子句的区别:

  • 如果在查询数据时没有指定where子句,那么会直接将表中所有的记录作为数据源来依次执行select语句。
  • 如果在查询数据时指定了where子句,那么在查询数据时会先根据where子句筛选出符合条件的记录,然后将符合条件的记录作为数据源来依次执行select语句。

where子句中可以指明一个或多个筛选条件,各个筛选条件之间用逻辑运算符AND或OR进行关联,下面给出了where子句中常用的比较运算符和逻辑运算符。

比较运算符:

运算符 说明
<、<=、>、>= 小于、小于等于、大于、大于等于
= 等于。NULL不安全,例如NULL=NULL的结果是NULL而不是TRUE(1)
<=> 等于。NULL安全,例如NULL<=>NULL的结果就是TRUE(1)
!=、<> 不等于
BETWEEN a0 AND a1 范围匹配。如果a0<=value<=a1,则返回TRUE(1)
IN(option1,option2,…) 如果是IN中的任意一个option,则返回TRUE(1)
IS NULL 如果是NULL,则返回TRUE(1)
IS NOT NULL 如果不是NULL,则返回TRUE(1)
LIKE 模糊匹配。%表示任意多个字符(包括0个),_表示任意一个字符

逻辑运算符:

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

英语不及格的同学及英语成绩 ( < 60 )

MySQL表的增删改查_第19张图片

语文成绩在 [80, 90] 分的同学及语文成绩

使用 AND 进行条件连接

MySQL表的增删改查_第20张图片

使用 BETWEEN … AND … 条件

MySQL表的增删改查_第21张图片

数学成绩是 58 或者 59 或者 98 或者 99 分的同学及数学成绩

使用 OR 进行条件连接

MySQL表的增删改查_第22张图片

使用 IN 条件

MySQL表的增删改查_第23张图片

姓孙的同学 及 孙某同学

% 匹配任意多个(包括 0 个)任意字符

MySQL表的增删改查_第24张图片

_ 匹配严格的一个任意字符

MySQL表的增删改查_第25张图片

语文成绩好于英语成绩的同学

WHERE 条件中比较运算符两侧都是字段。

MySQL表的增删改查_第26张图片

总分在 200 分以下的同学

MySQL表的增删改查_第27张图片

注意

  • 在where子句中不能使用select中指定的别名;
  • 查询数据时是先根据where子句筛选出符合条件的记录;
  • 然后再将符合条件的记录作为数据源来依次执行select语句。

where子句的执行是先于select语句的,所以在where子句中不能使用别名,如果在where子句中使用别名,那么在查询数据时就会产生报错。

MySQL表的增删改查_第28张图片

语文成绩 > 80 并且不姓孙的同学

MySQL表的增删改查_第29张图片

孙某同学,否则要求总成绩 > 200 并且 语文成绩 < 数学成绩 并且 英语成绩 > 80

MySQL表的增删改查_第30张图片

NULL 的查询

我们在刚刚创建的students表中查询qq号已知的同学。

MySQL表的增删改查_第31张图片

查询qq号未知的同学。

MySQL表的增删改查_第32张图片

我们需要注意的是与NULL值比较,不能使用=,需要使用<=>,使用=运算符无法得到正确的查询结果。

MySQL表的增删改查_第33张图片

结果排序

基本语法:

SELECT ... FROM table_name [WHERE ...] ORDER BY column [ASC | DESC] [, ...];

  • ASC 为升序(从小到大);
  • DESC 为降序(从大到小);
  • 默认为 ASC。

注意:没有 ORDER BY 子句的查询,返回的顺序是未定义的,永远不要依赖这个顺序

同学及数学成绩,按数学成绩升序显示

MySQL表的增删改查_第34张图片

同学及 qq 号,按 qq 号排序显示

NULL 视为比任何值都小,升序出现在最上面:

MySQL表的增删改查_第35张图片

NULL 视为比任何值都小,降序出现在最下面:

MySQL表的增删改查_第36张图片

查询同学各门成绩,依次按 数学降序,英语升序,语文升序的方式显示

多字段排序,排序优先级随书写顺序:

MySQL表的增删改查_第37张图片
说明一下:

  • order by子句中可以指明按照多个字段进行排序,每个字段都可以指明按照升序或降序进行排序,各个字段之间使用逗号隔开,排序优先级与书写顺序相同。
  • 比如上述SQL中,当两条记录的数学成绩相同时就会按照英语成绩进行排序,如果这两条记录的英语成绩也相同就会继续按照语文成绩进行排序,以此类推。

查询同学及总分,由高到低

MySQL表的增删改查_第38张图片

注意:

  • ORDER BY 子句中可以使用列别名;
  • 查询数据时是先根据where子句筛选出符合条件的记录;
  • 然后再将符合条件的记录作为数据源来依次执行select语句;
  • 最后再通过order by子句对select语句的执行结果进行排序。

MySQL表的增删改查_第39张图片

查询姓孙的同学或者姓曹的同学数学成绩,结果按数学成绩由高到低显示

此时,我们就需要结合where子句和order by子句同时进行查询了。

MySQL表的增删改查_第40张图片

筛选分页结果

基本语法:

从第0条记录开始,向后筛选出n条记录:

SELECT ... FROM table_name [WHERE ..] [ORDER BY ...] LIMIT n;

从第s条记录开始,向后筛选出n条记录:

SELECT ... FROM table_name [WHERE ...] [ORDER BY ...] LIMIT s, n;

从第s条记录开始,向后筛选出n条记录:

SELECT ... FROM table_name [WHERE ...] [ORDER BY ...] LIMIT n OFFSET s;

建议:对未知表进行查询时,最好加一条 LIMIT 1,避免因为表中数据过大,查询全表数据导致数据库卡死。

按 id 进行分页,每页 3 条记录,分别显示 第 1、2、3 页

MySQL表的增删改查_第41张图片

Update

基本语法:

UPDATE table_name SET column1=expr1 [, column2=expr2] ... [WHERE ...] [ORDER BY ...] [LIMIT ...];

将孙悟空同学的数学成绩修改为80分

我们先对原数据进行查看。

MySQL表的增删改查_第42张图片

然后对数据进行更新,最后查看更新后的数据。

MySQL表的增删改查_第43张图片

将曹孟德同学的数学成绩变更为 60 分,语文成绩变更为 70 分

查看原数据。

MySQL表的增删改查_第44张图片

然后对数据进行更新,最后查看更新后的数据。

MySQL表的增删改查_第45张图片

将总成绩倒数前三的 3 位同学的数学成绩加上 30 分

先查看总成绩倒数前三的 3 位同学。

MySQL表的增删改查_第46张图片

然后对数据更新完毕以后查看更新以后的结果。

MySQL表的增删改查_第47张图片

将所有同学的语文成绩更新为原来的 2 倍

先查看原数据;

MySQL表的增删改查_第48张图片

然后对数据进行更新以后在查看更新以后的数据。

MySQL表的增删改查_第49张图片

Delete

基本语法:

DELETE FROM table_name [WHERE ...] [ORDER BY ...] [LIMIT ...]

删除数据

删除孙悟空同学的考试成绩

我们先查看原数据,然后再删除数据,删除数据完成以后查看删除结果。

MySQL表的增删改查_第50张图片

删除整张表数据

在此,我们先创建一个测试表,插入一部分测试数据:

MySQL表的增删改查_第51张图片

此时我们删除数据以后查看结果。

MySQL表的增删改查_第52张图片

但是当我们在此插入数据以后,我们会发现自增 id 在原值上增长。

MySQL表的增删改查_第53张图片

此时我们查看表结构,会有 AUTO_INCREMENT=n 项。

MySQL表的增删改查_第54张图片

所以,当通过delete语句删除整表数据时,不会重置AUTO_INCREMENT=n字段,因此删除整表数据后插入数据对应的自增长id值会在原来的基础上继续增长。

截断表

基本语法:

TRUNCATE [TABLE] table_name

注意:这个操作慎用!!!

  • 只能对整表操作,不能像 DELETE 一样针对部分数据操作;
  • 实际上 MySQL 不对数据操作,所以比 DELETE 更快,但是TRUNCATE在删除数据的时候,并不经过真正的事物,所以无法回滚;
  • 会重置 AUTO_INCREMENT 项。

首先,我们准备一个测试用表,向其中插入一些数据。

MySQL表的增删改查_第55张图片

然后我们截断整表数据,然后在查看结果。

MySQL表的增删改查_第56张图片

此时我们在插入数据,会发现自增是重新开始的。

MySQL表的增删改查_第57张图片

此时我们查看表结构,会有 AUTO_INCREMENT=2 项。

MySQL表的增删改查_第58张图片

插入查询结果

基本语法:

INSERT INTO table_name [(column [, column ...])] SELECT ...

案例:删除表中的的重复复记录,重复的数据只能有一份

首先我们创建一张表:

MySQL表的增删改查_第59张图片

接下来向表中插入一些测试数据。

MySQL表的增删改查_第60张图片

在这儿我们还需要创建一张空表(no_duplicate_table)结构与duplicate_table一样。然后将将duplicate_table 的去重数据插入到 no_duplicate_table。

MySQL表的增删改查_第61张图片

接下来通过重命名表,实现原子的去重操作,最终查看结果可以发现已经操作成功了。

MySQL表的增删改查_第62张图片

聚合函数

函数 说明
COUNT([DISTINCT] expr) 返回查询到的数据的 数量
SUM([DISTINCT] expr) 返回查询到的数据的总和,不是数字没有意义
AVG([DISTINCT] expr) 返回查询到的数据的平均值,不是数字没有意义
MAX([DISTINCT] expr) 返回查询到的数据的最大值,不是数字没有意义
MIN([DISTINCT] expr) 返回查询到的数据的最小值,不是数字没有意义

统计班级共有多少同学

使用 * 做统计,不受 NULL 影响

MySQL表的增删改查_第63张图片

使用表达式做统计

MySQL表的增删改查_第64张图片

这种写法相当于在查询表中数据时,自行新增了一列列名为特定表达式的列,我们就是在用count函数统计该列中有多少个数据,等价于统计表中有多少条记录。

MySQL表的增删改查_第65张图片

统计班级收集的 qq 号有多少

注意,此时统计过程中NULL是不计入结果的。

MySQL表的增删改查_第66张图片

统计本次考试的数学成绩分数个数

COUNT(math) 统计的是全部成绩

MySQL表的增删改查_第67张图片

COUNT(DISTINCT math) 统计的是去重成绩数量

MySQL表的增删改查_第68张图片

统计数学成绩总分

MySQL表的增删改查_第69张图片

如果我们此时想要统计数学成绩小于60分的总分,配合where子句使用就可以了。可以看见没有结果,返回NULL;

MySQL表的增删改查_第70张图片

统计平均总分

MySQL表的增删改查_第71张图片

返回英语最高分

MySQL表的增删改查_第72张图片

返回 > 70 分以上的数学最低分

MySQL表的增删改查_第73张图片

group by子句的使用

基本语法:

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

案例:

  • 准备工作,创建一个雇员信息表
  • EMP员工表
  • DEPT部门表
  • SALGRADE工资等级表

员工表(emp)中包含如下字段:

  • 雇员编号(empno)。
  • 雇员姓名(ename)。
  • 雇员职位(job)。
  • 雇员领导编号(mgr)。
  • 雇佣时间(hiredate)。
  • 工资月薪(sal)。
  • 奖金(comm)。
  • 部门编号(deptno)。

部门表(dept)中包含如下字段:

  • 部门编号(deptno)。
  • 部门名称(dname)。
  • 部门所在地点(loc)。

工资等级表(salgrade)中包含如下字段:

  • 等级(grade)。
  • 此等级最低工资(losal)。
  • 此等级最高工资(hisal)。

进入scott数据库,在该数据库中就可以看到雇员信息表中的三张表。

MySQL表的增删改查_第74张图片

其中,部门表(dept)的表结构和内容如下:

MySQL表的增删改查_第75张图片

员工表(emp)的表结构和内容如下:

MySQL表的增删改查_第76张图片

工资等级表(salgrade)表结构和内容如下:

MySQL表的增删改查_第77张图片

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

在group by子句中指明按照部门号进行分组,在select语句中使用avg函数和max函数,分别查询每个部门的平均工资和最高工资。

MySQL表的增删改查_第78张图片

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

在group by子句中指明依次按照部门号和岗位进行分组,在select语句中使用avg函数和min函数,分别查询每个部门的每种岗位的平均工资和最低工资。

MySQL表的增删改查_第79张图片

注意:

  • group by子句中可以指明按照多个字段进行分组,各个字段之间使用逗号隔开,分组优先级与书写顺序相同。
  • 比如上述SQL中,当两条记录的部门号相同时,将会继续按照岗位进行分组。

HAVING 条件

基本语法:

SELECT ... FROM table_name [WHERE ...] [GROUP BY ...] [HAVING ...] [order by ...] [LIMIT ...];

where子句与having子句区别

  • where子句放在表名后面,而having子句必须搭配group by子句使用,放在group by子句的后面。
  • where子句是对整表的数据进行筛选,having子句是对分组后的数据进行筛选。
  • where子句中不能使用聚合函数和别名,而having子句中可以使用聚合函数和别名。

查询数据时,SQL中各语句的执行顺序如下:

  1. 根据where子句筛选出符合条件的记录。
  2. 根据group by子句对数据进行分组。
  3. 将分组后的数据依次执行select语句。
  4. 根据having子句对分组后的数据进行进一步筛选。
  5. 根据order by子句对数据进行排序。
  6. 根据limit子句筛选若干条记录进行显示。

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

  • 统计各个部门的平均工资;
  • having和group by配合使用,对group by结果进行过滤。

MySQL表的增删改查_第80张图片

MySQL表的增删改查_第81张图片

当然我们也可以使用别名的方式来进行筛选。

MySQL表的增删改查_第82张图片

你可能感兴趣的:(mysql,数据库)