MySQL必知必会04:操作表中的数据

阅读整理自《MySQL 必知必会》- 朱晓峰,详细内容请登录 极客时间 官网购买专栏。

添加数据

添加数据的语法结构:

insert into 表名 [(字段名 [,字段名] ...)] 
values (值的列表);

添加数据分为两种情况:插入数据记录和插入查询结果。

测试数据

mysql> describe goodsmaster;
+---------------+--------------+------+-----+---------+----------------+
| Field         | Type         | Null | Key | Default | Extra          |
+---------------+--------------+------+-----+---------+----------------+
| barcode       | text         | YES  |     | NULL    |                |
| goodname      | text         | YES  |     | NULL    |                |
| price         | decimal(5,2) | YES  |     | NULL    |                |
| itemnumber    | int          | NO   | PRI | NULL    | auto_increment |
| specification | text         | YES  |     | NULL    |                |
| unit          | text         | YES  |     | NULL    |                |
+---------------+--------------+------+-----+---------+----------------+
6 rows in set (0.01 sec)

插入数据记录

这里只给3个字段赋值,itemnumber、specification、unit不赋值:

insert into demo.goodsmaster (barcode, goodsname, price) values ('0004', '测试', 10);
mysql> insert into demo.goodsmaster (itemnumber, barcode, goodname, specification, unit, price) values (4, '004', 'ruler', 'tangle', 'a', 0.5);
Query OK, 1 row affected (0.00 sec)

mysql> select * from demo.goodsmaster;
+---------+-----------------+-------+------------+---------------+------+
| barcode | goodname        | price | itemnumber | specification | unit |
+---------+-----------------+-------+------------+---------------+------+
| 004     | ruler           |  0.50 |          4 | tangle        | a    |
| 0004    | 测试            | 10.00 |        102 | NULL          | NULL |
+---------+-----------------+-------+------------+---------------+------+
7 rows in set (0.00 sec)

在插入一条数据记录的时候,必须要考虑字段约束的 3 种情况:

  • 如果字段允许为空,而我们没有给它赋值,那么 MySQL 会自动给它们赋予空值。

    “specification”, "unit"字段都允许为空,因此如果数据插入语句没有指定这几个字段的值,MySQL 会自动插入空值

  • 如果字段是主键,就不能为空,这个时候,MySQL 会按照添加的约束进行处理。比如字段"itemnumber"是主键,不能为空,而我们定义了自增约束,所以 MySQL 自动在之前的最大值基础上加了1。因此,itemnumber 也有了自己该有的值

  • 如果有一个字段定义不能为空,又不是主键,当插入一条数据记录的时候,就必须给这个记录赋值

如果操作违反了字段的约束限制,会出现报错。

比如说,尝试把表 demo.goodsmaster 的字段 “speicification” 改为不能为空:

mysql> alter table goodsmaster modify specification text not null;
ERROR 1138 (22004): Invalid use of NULL value

表里已经有一条没有给字段"specification"赋值的数据记录,这跟给字段“specification”添加非空约束的操作冲突了,

要把字段“speicification”的值为空的数据记录删除,然后再修改字段约束:

mysql> delete from goodsmaster where specification is NULL;
Query OK, 1 row affected (0.01 sec)

删除数据记录之后,再运行上面的语句,给字段"specification"添加非空约束,就成功了:

mysql> alter table goodsmaster modify specification text not null;
Query OK, 0 rows affected (0.17 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> describe goodsmaster;
+---------------+--------------+------+-----+---------+----------------+
| Field         | Type         | Null | Key | Default | Extra          |
+---------------+--------------+------+-----+---------+----------------+
| barcode       | text         | YES  |     | NULL    |                |
| goodname      | text         | YES  |     | NULL    |                |
| price         | decimal(5,2) | YES  |     | NULL    |                |
| itemnumber    | int          | NO   | PRI | NULL    | auto_increment |
| specification | text         | NO   |     | NULL    |                |
| unit          | text         | YES  |     | NULL    |                |
+---------------+--------------+------+-----+---------+----------------+
6 rows in set (0.01 sec)

验证一下非空约束,尝试部分插入一条数据记录,不给字段 specification 赋值:

mysql> insert into demo.goodsmaster (barcode, goodname, price) values ('0004', '测试', 10);
ERROR 1364 (HY000): Field 'specification' doesn't have a default value

报错提示字段"specification"没有默认值,也就是说,这个字段不能为空,如果插入数据时不给它赋值,就必须给它一个默认值。

部分插入一条数据记录是可以的,但前提是,没有赋值的字段,一定要让 MySQL 知道如何处理,比如可以为空、有默认值,或者是自增约束字段,等等,否则,MySQL 会提示错误的。


插入查询结果

MySQL 支持把查询的结果插入到数据表中,可以指定字段,甚至是数值,插入到数据表中。语法结构如下:

insert into 表名 (字段名)
select 字段名或值
from 表名
where 条件

把一个查询结果插入数据表中的方式,可以提高添加数据的效率。

比如,历史流水表设计与流水表非常类似。不同的是,历史流水表增加了一些字段来标识历史流水的状态,比如日结时间字段,是用来记录日结操作是什么时候进行的。

insert into 历史流水表 (日结时间字段,其他字段)
select 获取当前时间函数,其他字段
from 流水表

删除数据

数据删除的语法很简单:

delete from 表名 
where 条件

删除全部数据:

mysql> select * from demo.test1;
+------+-----------+-------+------------+
| bar  | goodsname | price | itemnumber |
+------+-----------+-------+------------+
| 001  | book      | 29.51 |          1 |
| 002  | pen       |  5.17 |          2 |
| 003  | rubber    |  2.42 |          3 |
+------+-----------+-------+------------+
3 rows in set (0.00 sec)

mysql> delete from demo.test1;
Query OK, 3 rows affected (0.01 sec)

mysql> select * from demo.test1;
Empty set (0.00 sec)

如果在 Workbench 中运行上面的 SQL 语句,会提示错误。因为 Workbench 自动处于安全模式,它要求对数据的删除或修改操作中必须包含 WHERE 条件。而且,这个 WHERE 条件中,必须用到主键约束或者唯一性约束的字段。MySQL 的这种安全性设置,主要就是为了防止删除或者修改数据时出现误操作,导致删除或修改了不相关的数据。

mysql> select * from demo.goodsmaster;
+---------+----------+-------+------------+---------------+------+
| barcode | goodname | price | itemnumber | specification | unit |
+---------+----------+-------+------------+---------------+------+
| 001     | book     |  1.50 |          1 | book1         | a    |
| 004     | ruler    |  0.50 |          4 | tangle        | a    |
+---------+----------+-------+------------+---------------+------+
2 rows in set (0.00 sec)

mysql> delete from demo.goodsmaster where itemnumber>=1;
Query OK, 2 rows affected (0.01 sec)

mysql> select * from demo.goodsmaster;
Empty set (0.00 sec)

修改数据

数据修改语法:

update 表名 
set 字段名=where 条件 

不要修改主键字段的值。因为主键是数据记录的唯一标识,如果修改了主键的值,就有可能会破坏数据的完整性。

mysql> update demo.goodsmaster set price=2.5 where itemnumber=1;
Query OK, 1 row affected (0.01 sec)
Rows matched: 1  Changed: 1  Warnings: 0

mysql> select * from demo.goodsmaster;
+---------+----------+-------+------------+---------------+------+
| barcode | goodname | price | itemnumber | specification | unit |
+---------+----------+-------+------------+---------------+------+
| 001     | book     |  2.50 |          1 | book1         | a    |
+---------+----------+-------+------------+---------------+------+
1 row in set (0.00 sec)

查询数据

查询语句的语法结构:

select *|字段列表
from 数据源
where 条件
group by 字段
having 条件
order by 字段
limit 起始点,行数 
  • SELECT:是查询关键字,表示要做一个查询。*是一个通配符,表示要查询表中所有的字段。也可以把要查询的字段罗列出来,这样,查询的结果可以只显示想要查询的字段内容
  • WHERE:表示查询条件。可以把要查询的数据所要满足的条件,放在 WHERE 关键字之后
  • GROUP BY:表示查询结果要分组,经常与 MySQL 的聚合函数一起使用
  • HAVING:用于筛选查询结果,跟 WHERE 类似

FROM

FROM 关键字表示查询的数据源。可以把要查询的数据表名,直接写在 FROM 关键字之后。在关联表中 FROM 关键字后面,还可以跟着更复杂的数据表联接。数据源也不一定是表,也可以是一个查询的结果。比如下面的查询:

mysql> select a.goodname, a.price from
    -> (select * from demo.goodsmaster) as a;
+----------+-------+
| goodname | price |
+----------+-------+
| book     |  2.50 |
+----------+-------+
1 row in set (0.00 sec)

select * from demo.goodsmaster 部分叫做派生表(derived table),或者子查询(subquery),意思是我们把一个查询结果数据集当做一个虚拟的数据表来看待。MySQL 规定,必须要用 AS 关键字给这个派生表起一个别名。在这张图中,给这个派生表起了个名字,叫做 a 。

ORDER BY

ORDER BY 的作用,是告诉 MySQL,查询结果如何排序。ASC 表示升序,DESC 表示降序。

mysql> select * from demo.goodsmaster;
+---------+----------+-------+------------+---------------+------+
| barcode | goodname | price | itemnumber | specification | unit |
+---------+----------+-------+------------+---------------+------+
| 001     | book     |  2.50 |          1 | book1         | a    |
| 002     | ruler    |  1.00 |        104 | NULL          | NULL |
| 003     | pen      |  2.00 |        105 | NULL          | NULL |
| 003     | pencil   |  1.60 |        106 | NULL          | NULL |
| 001     | notebook |  3.00 |        107 | NULL          | NULL |
+---------+----------+-------+------------+---------------+------+
5 rows in set (0.00 sec)

mysql> select * from demo.goodsmaster order by barcode asc, price desc;
+---------+----------+-------+------------+---------------+------+
| barcode | goodname | price | itemnumber | specification | unit |
+---------+----------+-------+------------+---------------+------+
| 001     | notebook |  3.00 |        107 | NULL          | NULL |
| 001     | book     |  2.50 |          1 | book1         | a    |
| 002     | ruler    |  1.00 |        104 | NULL          | NULL |
| 003     | pen      |  2.00 |        105 | NULL          | NULL |
| 003     | pencil   |  1.60 |        106 | NULL          | NULL |
+---------+----------+-------+------------+---------------+------+
5 rows in set (0.00 sec)

LIMIT

LIMIT 的作用是告诉 MySQL 只显示部分查询的结果。MySQL中,起始位置的起点是0

mysql> select * from demo.goodsmaster limit 1,2;
+---------+----------+-------+------------+---------------+------+
| barcode | goodname | price | itemnumber | specification | unit |
+---------+----------+-------+------------+---------------+------+
| 002     | ruler    |  1.00 |        104 | NULL          | NULL |
| 003     | pen      |  2.00 |        105 | NULL          | NULL |
+---------+----------+-------+------------+---------------+------+
2 rows in set (0.00 sec)

这里的“LIMIT 1,2”中,“1”表示起始位置,1 表示从第 2 条记录开始;“2”表示 2 条数据。因此,“LIMIT 1,2”就表示从第 2 条数据开始,显示 2 条数据,也就是显示了第 2、3 条数据。


小结

insert into 表名 [(字段名 [,字段名] ...)] values (值的列表);
 
insert into 表名 (字段名)
select 字段名或值
from 表名
where 条件
 
delete from 表名
where 条件
 
update 表名
set 字段名=where 条件

select *|字段列表
from 数据源
where 条件
group by 字段
having 条件
order by 字段
limit 起始点,行数

如果把查询的结果插入到表中时,导致主键约束或者唯一性约束被破坏了,就可以用“ON DUPLICATE”关键字进行处理。这个关键字的作用是,告诉 MySQL,如果遇到重复的数据,该如何处理。

假设用户有 2 个各自独立的门店,分别有自己的系统。现在需要引入连锁经营的模式,把 2 个店用一套系统统一管理。那么首先遇到的问题就是,需要进行数据整合。

门店 A 的商品信息表是“demo.goods1”,代码如下:

mysql> select * from demo.goods1;
+------------+---------+-----------+---------------+---------+------------+
| itemnumber | barcode | goodsname | specification | unit    | salesprice |
+------------+---------+-----------+---------------+---------+------------+
|          1 | 001     | book      | 16k           | a       |      88.00 |
|          2 | 002     | pen       | 10in          | package |      10.00 |
|          3 | 003     | rubber    | NULL          | a       |       2.00 |
+------------+---------+-----------+---------------+---------+------------+
3 rows in set (0.00 sec)

门店 B 的商品信息表是“demo.goods2”:

ysql> select * from demo.goods2;
+------------+---------+-----------+---------------+------+------------+
| itemnumber | barcode | goodsname | specification | unit | salesprice |
+------------+---------+-----------+---------------+------+------------+
|          1 | 001     | tech book | NULL          | NULL |      66.00 |
|          4 | 004     | bread     | NULL          | NULL |       1.50 |
+------------+---------+-----------+---------------+------+------------+
2 rows in set (0.00 sec)

假设要把门店 B 的商品数据,插入到门店 A 的商品表中去,如果有重复的商品编号,就用门店 B 的条码,替换门店 A 的条码,用门店 B 的商品名称,替换门店 A 的商品名称;如果没有重复的编号,就直接把门店 B 的商品数据插入到门店 A 的商品表中。

mysql> insert into demo.goods1
    -> select * from demo.goods2 as a
    -> on duplicate key update barcode=a.barcode, goodsname=a.goodsname;
Query OK, 3 rows affected (0.01 sec)
Records: 2  Duplicates: 1  Warnings: 0

mysql> select * from demo.goods1;
+------------+---------+-----------+---------------+---------+------------+
| itemnumber | barcode | goodsname | specification | unit    | salesprice |
+------------+---------+-----------+---------------+---------+------------+
|          1 | 001     | tech book | 16k           | a       |      88.00 |
|          2 | 002     | pen       | 10in          | package |      10.00 |
|          3 | 003     | rubber    | NULL          | a       |       2.00 |
|          4 | 004     | bread     | NULL          | NULL    |       1.50 |
+------------+---------+-----------+---------------+---------+------------+
4 rows in set (0.00 sec)

MySQL 数据插入:https://dev.mysql.com/doc/refman/8.0/en/insert.html

MySQL 数据更新:https://dev.mysql.com/doc/refman/8.0/en/update.html

MySQL 数据查询:https://dev.mysql.com/doc/refman/8.0/en/select.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值