MySQL —— 表的增删查改(一)

目录

表的增删查改(一)

一、create

1. 单行数据+全列插入 

2. 多行数据+指定列插入

3. 插入否则更新

4. 替换

二、Retrieve

1. select列

1. 全列查询

2. 指定列查询

3. 查询字段为表达式

4. 为查询结果指定别名

5. 结果去重

2. where条件

1. 查询英语不及格的同学及英语成绩 ( < 60 )

2. 查询语文成绩在 [80, 90] 分的同学及语文成绩

3. 查询数学成绩是 65 或者 85 或者 98 或者 99 分的同学及数学成绩

4. 查询姓孙的同学 及 孙某同学

5. 查询语文成绩好于英语成绩的同学

6. 查询总分在 200 分以下的同学

7. 查询语文成绩 > 80 并且不姓孙的同学

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

9. NULL 的查询

3. 结果排序

1. 查询同学及数学成绩,按数学成绩升序显示

2. 查询同学及QQ号,按QQ号升序显示

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

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

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

4. 筛选分页结果

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

三、Updata

1. 将孙悟空同学的数学成绩变更为 80 分

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

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

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

四、Delete

1. 删除数据

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

2. 删除整张表数据

2. 截断表

五、插入查询结果


表的增删查改(一)

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

一、create

语法:

INSERT [INTO] table_name [(column [, column] ...)]
VALUES (value_list) [, (value_list)] ...
value_list: value, [, value] ...

为了进行演示,下面创建一个学生表,表当中包含自增长的主键id、学号、姓名和qq号。如下:

--创建一个学生表:
create table students(
    id int unsigned primary key auto_increment comment '主键',
    sn int not null unique comment '学号',
    name varchar(20) not null comment '姓名',
    qq varchar(20) comment 'qq号'
);

创建表完毕后查看表结构,可以看到表结构如下:

1. 单行数据+全列插入 

        使用insert语句向学生表中插入记录,每次向表中插入一条记录,并且插入记录时不指定column列表(就是id、sn、name、qq),表示按照表中默认的列顺序进行全列插入,因此插入的每条记录中的列值需要按表列顺序依次列出。如下:

2. 多行数据+指定列插入

使用insert语句也可以一次向表中插入多条记录,插入的多条记录之间使用逗号隔开,并且插入记录时可以只指定某些列进行插入。如下:

说明: 在插入记录时,只有允许为空的列或自增长字段可以不指定值插入,不允许为空的列必须指定值插入,否则会报错。

3. 插入否则更新

向表中插入记录时,如果待插入记录中的主键或唯一键已经存在,那么就会因为主键冲突或唯一键冲突导致插入失败。如下: 

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

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

语法如下:

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

执行插入否则更新的SQL后,可以通过受影响的数据行数来判断本次数据的插入情况:

  • 0 rows affected:表中有冲突数据,但冲突数据的值和指定更新的值相同。
  • 1 row affected:表中没有冲突数据,数据直接被插入。
  • 2 rows affected:表中有冲突数据,并且数据已经被更新。

4. 替换

-- 主键 或者 唯一键 没有冲突,则直接插入;
-- 主键 或者 唯一键 如果冲突,则删除后再插入
REPLACE INTO students (sn, name) VALUES (20001, '曹阿瞒');
Query OK, 2 rows affected (0.00 sec)
-- 1 row affected: 表中没有冲突数据,数据被插入
-- 2 row affected: 表中有冲突数据,删除后重新插入

二、Retrieve

查找数据 

语法如下: 

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

案例: 

-- 创建表结构
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 '英语成绩'
);
-- 插入测试数据
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. select列

1. 全列查询

在查询数据时直接用*代替column列表,表示进行全列查询,这时将会显示被筛选出来的记录的所有列信息。如下: 

通常情况下不建议使用 * 进行全列查询
  1. 查询的列越多,意味着需要传输的数据量越大;
  2. 可能会影响到索引的使用。

2. 指定列查询

在查询数据时也可以只对指定的列进行查询,这时将需要查询的列在column列表列出即可。如下: 

3. 查询字段为表达式

查询数据时,column列表中除了能罗列表中存在的列名外,我们也可以将表达式罗列到column列表中。如下: 

既然可以执行表达式,那么就可以有如下操作:

4. 为查询结果指定别名

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

5. 结果去重

查询成绩表时指定查询数学成绩对应的列,可以看到数学成绩中有重复的分数。如果想要对查询结果进行去重操作,可以在SQL中的select后面带上distinct。如下: 

2. where条件

where子句:

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

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

比较运算符:

运算符 说明
>、>=、<、<= 大于、大于等于、小于、小于等于
=
等于,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),否则为FALSE(0)
OR
任意一个条件为TRUE(1),则结果为TRUE(1),否则为FALSE(0)
NOT
条件为TRUE(1),则结果为FALSE(0);条件为FALSE(0),则结果为TRUE(1)

在开始下面where子句使用前,可以先看看这个表,想一想下面每个题目怎么使用where快速查询出结果

1. 查询英语不及格的同学及英语成绩 ( < 60 )

2. 查询语文成绩在 [80, 90] 分的同学及语文成绩

 我们还可以使用between a0 and a1;它代表的是一个闭区间

3. 查询数学成绩是 65 或者 85 或者 98 或者 99 分的同学及数学成绩

 我们还可以使用in条件

4. 查询姓孙的同学 及 孙某同学

5. 查询语文成绩好于英语成绩的同学

6. 查询总分在 200 分以下的同学

需要注意的是,我们这里个chinese+math+english取了别名为总分,如果你想在where中使用这个别名是不可以的:

原因:我们要查询的是总分小于200的同学,正常的逻辑,你如果有这张表,你应该是先计算出所有同学的总分,然后再进行筛选小于200的同学。where子句就是做筛选的,筛选之前就需要把总分计算好,但是你直接使用这个别名,where子句根本看不到(不认识);牢记:where子句不可以使用别名;

7. 查询语文成绩 > 80 并且不姓孙的同学

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

9. NULL 的查询

这里用之前演示新增数据的学生表来演示NULL查询,学生表中的内容如下:

 查询有qq号的同学:

查询没有qq号的同学:

当然还可以这样:

在与NULL值作比较的时候可以使用<=>运算符,使用=运算符无法得到正确的查询结果。如下: 

因为=运算符是NULL不安全的,使用=运算符将任何值与NULL作比较,得到的结果都是NULL。如下:

但是<=>运算符是NULL安全的,使用<=>运算符将NULL和NULL作比较得到的结果为TRUE(1),将非NULL值与NULL作比较得到的结果为FALSE(0)。如下:

3. 结果排序

 语法如下:

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

1. 查询同学及数学成绩,按数学成绩升序显示

 如果你想要降序排序,使用desc:

2. 查询同学及QQ号,按QQ号升序显示

 说明一下: NULL值视为比任何值都小,因此排升序时出现在最上面。

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

 我们发现数学成绩确实是按照降序进行排列的,但是英语和语文却不是;

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

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

需要注意的是,在order by子句中可以使用select中指定的别名:

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

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

 这里的where子句中的()你也可以不加,加上更加直观;

4. 筛选分页结果

从第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;

建议: 对未知表进行查询时最好在查询SQL后加上limit 1,避免在查询全表数据时因为表中数据过大而导致数据库卡死。

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

这里使用成绩表中的数据来演示分页查询,成绩表中的内容如下: 

查询第1页记录时在查询全表数据的SQL后,加上limit子句指明从第0条记录开始,向后筛选出3条记录。如下:

查询第2页记录时在查询全表数据的SQL后,加上limit子句指明从第3条记录开始,向后筛选出3条记录。如下:

查询第3页记录时在查询全表数据的SQL后,加上limit子句指明从第6条记录开始,向后筛选出3条记录。如下:

说明一下: 如果从表中筛选出的记录不足n个,则筛选出几个就显示几个

三、Updata

修改数据 

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

1. 将孙悟空同学的数学成绩变更为 80 分

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

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

 在修改数据之前,先查看总成绩倒数前三的3位同学的数学成绩。如下:

在update语句中指明要将筛选出来的记录的数学成绩加上30分,并在修改后再次查看数据确保数据成功被修改。如下:

需要注意的是,MySQL中不支持+=这种复合赋值运算符,此外,这里在查看更新后的数据时不能查看总成绩倒数前三的3位同学,因为之前总成绩倒数前三的3位同学,数学成绩加上30分后可能就不再是倒数前三了。如下:

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

注意: 更新全表的语句慎用! 

四、Delete

删除数据

语法如下: 

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

1. 删除数据

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

2. 删除整张表数据

创建一张测试表,表中包含一个自增长的主键id和姓名,并插入一些数据。如下: 

在delete语句中只指明要删除数据的表名,而不通过where、order by和limit指明筛选条件,这时将会删除整张表的数据。如下:

再向表中插入一些数据,在插入数据时不指明自增长字段的值,这时会发现插入数据对应的自增长id值是在之前的基础上继续增长的。如下:

查看创建表时的相关信息时可以看到,有一个AUTO_INCREMENT=N的字段,该字段表示下一次插入数据时自增长字段的值应该为n。如下:

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

注意: 删除整表操作要慎用!

2. 截断表

语法:

TRUNCATE [TABLE] table_name;

说明一下:

  • truncate只能对整表操作,不能像delete一样针对部分数据操作。
  • truncate实际上不对数据操作,所以比delete更快。
  • truncate在删除数据时不经过真正的事务,所以无法回滚。
  • truncate会重置AUTO_INCREMENT=n字段。

创建一张测试表,表中包含一个自增长的主键id和姓名,并插入一些数据。如下:

在truncate语句中只指明要删除数据的表名,这时便会删除整张表的数据,但由于truncate实际不对数据操作,因此执行truncate语句后看到影响行数为0。如下:

再向表中插入一些数据,在插入数据时不指明自增长字段的值,这时会发现插入数据对应的自增长id值是重新从1开始增长的。如下:

查看创建表时的相关信息时也可以看到,有一个AUTO_INCREMENT=n的字段,该字段表示下一次插入数据时自增长字段的值应该为n。如下:

但是当通过truncate语句删除整表数据时,会重置AUTO_INCREMENT字段,因此截断表后插入数据对应的自增长id值会重新从1开始增长。如下:

注意: 截断表操作要慎用!

五、插入查询结果

语法如下: 

INSERT [INTO] table_name [(column1 [, column2] ...)] SELECT ... [WHERE ...] [ORDER BY ...] [LIMIT ...];

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

创建一张测试表,表中包含id和姓名,并插入一些数据(有重复的)如下: 

现在要求删除测试表中重复的数据,思路如下:

  • 创建一张临时表,该表的结构与测试表的结构相同。
  • 以去重的方式查询测试表中的数据,并将查询结果插入到临时表中。
  • 将测试表重命名为其他名字,再将临时表重命名为测试表的名字,实现原子去重操作。

由于临时表的结构与测试表相同,因此在创建临时表的时候可以借助like进行创建。如下: 

通过insert语句将去重查询后的结果插入到临时表中,由于临时表和测试表的结构相同,并且select进行的是全列查询,因此在插入时不用在表名后指明column列表。如下:

将测试表重命名为其他名字(相当于对去重前的数据进行备份,如果不需要可以直接删除),将临时表重命名为测试表的名字,这时便完成了表中数据的去重操作。如下:

猜你喜欢

转载自blog.csdn.net/sjsjnsjnn/article/details/128959848
今日推荐