MySQL表的增删查改

1. 插入数据insert

CRUD中的"C",Create,即向表中插入新的数据,常用sql命令:insert

insert可以选定列插入,并x`支持同时插入多行数据(中括号内为可选项)

sql 复制代码
insert [into] 表名 [(column1, column2, column3...)] values (value1), (value2), (value3)...

value必须与指定的列匹配,不指定列,默认就是全列插入。

sql 复制代码
mysql> insert into students (sn, name, qq) value (103, '子乔', 451592222), (104, '小贤', 451593333), (105, '一菲', 123456789);
Query OK, 3 rows affected (0.01 sec)
Records: 3  Duplicates: 0  Warnings: 0

mysql> select * from students;
+----+-----+--------+-----------+
| id | sn  | name   | qq        |
+----+-----+--------+-----------+
|  1 | 101 | 张伟   | 451591111 |
|  2 | 102 | 张伟   | 451591111 |
|  3 | 103 | 子乔   | 451592222 |
|  4 | 104 | 小贤   | 451593333 |
|  5 | 105 | 一菲   | 123456789 |
+----+-----+--------+-----------+

insert插入数据时,若发生主键或唯一键冲突,一般情况下MySQL会报错 。在insert语句后接上on duplicate key update col1=val1, col2=val2...,当发生主键或者唯一键冲突时,冲突元组列col1, col2...的值修改为用户指定的值val1, val2...。

sql 复制代码
mysql> select * from students;
+----+-----+--------+-----------+
| id | sn  | name   | qq        |
+----+-----+--------+-----------+
|  1 | 101 | 张伟   | 451591111 |
|  2 | 106 | 关谷   | 451594567 |
|  4 | 104 | 小贤   | 451593333 |
|  5 | 105 | 一菲   | 123456789 |
|  9 | 107 | 婉瑜   | 123123123 |
+----+-----+--------+-----------+
5 rows in set (0.00 sec)

mysql> insert into students value (2, 103, '子乔', 451522222);
ERROR 1062 (23000): Duplicate entry '2' for key 'PRIMARY' #这里发生了主键冲突,无法插入,报错

mysql> insert into students value (2, 103, '子乔', 451522222) on duplicate key update sn='103', name='子乔', qq='451522222';#这次虽然依然主键冲突,但是修改了冲突那一行的一些值
Query OK, 2 rows affected (0.00 sec)

mysql> select * from students;
+----+-----+--------+-----------+
| id | sn  | name   | qq        |
+----+-----+--------+-----------+
|  1 | 101 | 张伟   | 451591111 |
|  2 | 103 | 子乔   | 451522222 |
|  4 | 104 | 小贤   | 451593333 |
|  5 | 105 | 一菲   | 123456789 |
|  9 | 107 | 婉瑜   | 123123123 |
+----+-----+--------+-----------+
5 rows in set (0.00 sec)

replace,语法和insert基本一样

sql 复制代码
replace [into] 表名 [(column, column, column...)] values (value_list), (value_list), (value_list)...
  • 主键或唯一键冲突,删除后插入

  • 主键或唯一键不冲突,直接插入


2. 查询数据select

CRUD中的"R",Retrive,即向从表中查询数据,常用sql命令:select,select搭配一些限制命令使用,如:distinct, where, order, limit等

distinct

结果去重,对于重复的数据只显示一次。

sql 复制代码
SELECT DISTINCT column1, column2, column3 FROM your_table;

注意:distinct保证的是紧随其后所有列组合在一起的唯一性

sql 复制代码
mysql> select * from exam;
+----+--------+---------+------+---------+
| id | name   | chinese | math | english |
+----+--------+---------+------+---------+
|  1 | 张三   |      19 |   36 |      24 |
|  2 | 李四   |      11 |   83 |      83 |
|  3 | 王五   |      67 |   83 |      14 |
|  4 | 赵六   |      22 |   68 |      74 |
|  5 | 小明   |      64 |   99 |      74 |
|  6 | 张飞   |      23 |   43 |      48 |
|  7 | 刘备   |      28 |   97 |       9 |
|  8 | 刘备   |      55 |   97 |      71 |
+----+--------+---------+------+---------+
8 rows in set (0.00 sec)

mysql> select distinct math from exam; #保证数学成绩math的唯一性
+------+
| math |
+------+
|   36 |
|   83 |
|   68 |
|   99 |
|   43 |
|   97 |
+------+
6 rows in set (0.00 sec)

mysql> select distinct name,math from exam; #保证姓名+数学成绩的唯一性
+--------+------+
| name   | math |
+--------+------+
| 张三   |   36 |
| 李四   |   83 |
| 王五   |   83 |
| 赵六   |   68 |
| 小明   |   99 |
| 张飞   |   43 |
| 刘备   |   97 |
+--------+------+
7 rows in set (0.00 sec)
# 34行和35行,姓名不同,数学成绩相同,整体不同,可以共存
# "刘备 97"存在两行,因此被去重了

where

比较运算符

运算符 说明
大于
>= 大于等于
< 小于
<= 小于等于
= 等于,NULL 不安全,例如 NULL = NULL 的结果是 NULL
<=> 等于,NULL 安全,例如 NULL <=> NULL 的结果是 TRUE(1)
!=, <> 不等于
BETWEEN a AND b 范围匹配,全闭区间[a, b],如果 a <= value <= ab,返回 TRUE(1)
IN 如果是 option 中的任意一个,返回 TRUE(1)
IS NULL 是 NULL
IS NOT NULL 不是 NULL
LIKE 模糊匹配。% 表示任意多个(包括 0 个)任意字符;_ 表示一个字符

一般情况下,NULL不安全,不参与比较,因此只要运算符左右任一侧带有NULL,返回结果为NULL。特殊情况是<=>

逻辑运算符

  • AND,与
  • OR,或
  • NOT,非

order

默认是升序

asc: 升序

desc: 降序

limit

对显式行数的限制

  • limit n: 从开始连续显示n行
  • limit s,n: 从第s行开始,连续显示n行(起始行下标为0)
  • limit n offset s:同上

使用limit对表进行分页显示

sql 复制代码
mysql> select * from exam order by id limit 3 offset 0;
+----+--------+---------+------+---------+
| id | name   | chinese | math | english |
+----+--------+---------+------+---------+
|  1 | 张三   |      35 |   36 |      24 |
|  2 | 李四   |      27 |   83 |      83 |
|  3 | 王五   |      83 |   83 |      14 |
+----+--------+---------+------+---------+
3 rows in set (0.00 sec)

mysql> select * from exam order by id limit 3 offset 3;
+----+--------+---------+------+---------+
| id | name   | chinese | math | english |
+----+--------+---------+------+---------+
|  4 | 赵六   |      38 |   68 |      74 |
|  5 | 小明   |      80 |   99 |      82 |
|  6 | 张飞   |      39 |   43 |      48 |
+----+--------+---------+------+---------+
3 rows in set (0.00 sec)

mysql> select * from exam order by id limit 3 offset 6;
+----+--------+---------+------+---------+
| id | name   | chinese | math | english |
+----+--------+---------+------+---------+
|  7 | 刘备   |      44 |   97 |       9 |
|  8 | 刘备   |      71 |   97 |      71 |
| 10 | 悟空   |      98 | NULL |    NULL |
+----+--------+---------+------+---------+
3 rows in set (0.00 sec)

mysql> select * from exam order by id limit 3 offset 9;
+----+-----------+---------+------+---------+
| id | name      | chinese | math | english |
+----+-----------+---------+------+---------+
| 11 | 张三丰    |      76 |   60 |      60 |
+----+-----------+---------+------+---------+
1 row in set (0.00 sec)

3. 更新数据update

CRUD中的"U",Update,即更新表中的某些数据,常用sql命令:update

更新筛选出来的数据记录,不加筛选字段默认更新整表数据,要小心谨慎!

sql 复制代码
update 表名 set col1=val, col2=val... /*筛选字段:*/ [where...][order by...][limit...]

Demo:将总成绩倒数前三的同学的英语成绩都加上10分

sql 复制代码
mysql> select name,english,chinese+math+english as total from exam order by total limit 3;
+--------+---------+-------+
| name   | english | total |
+--------+---------+-------+
| 张三   |      24 |   125 |
| 刘备   |       9 |   150 |
| 张飞   |      48 |   160 |
+--------+---------+-------+
3 rows in set (0.00 sec)

mysql> update exam set english=english+10 order by chinese+math+english asc limit 3;
Query OK, 3 rows affected (0.00 sec)
Rows matched: 3  Changed: 3  Warnings: 0

mysql> select name,english,chinese+math+english as total from exam order by total limit 3;
+--------+---------+-------+
| name   | english | total |
+--------+---------+-------+
| 张三   |      34 |   135 |
| 刘备   |      19 |   160 |
| 张飞   |      58 |   170 |
+--------+---------+-------+

4. 删除数据delete

CRUD中的"D",Delete,即删除表中的某些数据,常用sql命令:delete

删除筛选出来的数据记录,不加筛选字段默认删除整表数据,要小心谨慎!

sql 复制代码
delete from 表名 /*筛选字段:*/ [where...][order by...][limit...]

清空表中所有内容:

sql 复制代码
delete from 表名
truncate [table] 表名 #截断表

区别:

  1. delete可以选择对表的部分或全部作删除,而truncate只能对整表操作
  2. truncate实际上MySQL不对数据操作,所以比delete更快,但是TRUNCATE在删除数据的时候,并不经过真正的事务,所以无法回滚。
  3. truncate会重置auto_increment项,delete不会

5. 聚合函数

将同一列中的值,作某些具体操作,统计得到一个结果,称为"聚合"。如,学生成绩表中,求出数学成绩的总和,就是对math列的全部值累加,得到最终结果。

函数 说明
count(* | expr) 返回查询到的数据的数量
sum(expr) 返回查询到的数据的总和
avg(expr) 返回查询到的数据的平均值
max(expr) 返回查询到的数据的最大值
min(expr) 返回查询到的数据的最小值
  1. 聚合函数可以加上distinct语句,即去重后再统计,如count(distinct [col1],[col2], ...)

    sql 复制代码
    mysql> select ename, deptno from emp;
    +--------+--------+
    | ename  | deptno |
    +--------+--------+
    | SMITH  |     20 |
    | ALLEN  |     30 |
    | WARD   |     30 |
    | JONES  |     20 |
    | MARTIN |     30 |
    | BLAKE  |     30 |
    | CLARK  |     10 |
    | SCOTT  |     20 |
    | KING   |     10 |
    | TURNER |     30 |
    | ADAMS  |     20 |
    | JAMES  |     30 |
    | FORD   |     20 |
    | MILLER |     10 |
    +--------+--------+
    14 rows in set (0.00 sec)
    
    mysql> select count(deptno) from emp;
    +---------------+
    | count(deptno) |
    +---------------+
    |            14 |
    +---------------+
    1 row in set (0.00 sec)
    
    mysql> select count(distinct deptno) from emp; #一共有多少个不同的部门
    +------------------------+
    | count(distinct deptno) |
    +------------------------+
    |                      3 |
    +------------------------+
    1 row in set (0.00 sec)
  2. 对于数学运算的聚合函数,无法计算的返回0(例如:字符串类型可以求最大值最小值,但是无法求总和或平均值)

    sql 复制代码
    mysql> select deptno, max(ename) from emp group by deptno;
    +--------+------------+
    | deptno | max(ename) |
    +--------+------------+
    |     10 | MILLER     |
    |     20 | SMITH      |
    |     30 | WARD       |
    +--------+------------+
    3 rows in set (0.00 sec)
    
    mysql> select deptno, sum(ename) from emp group by deptno;
    +--------+------------+
    | deptno | sum(ename) |
    +--------+------------+
    |     10 |          0 |
    |     20 |          0 |
    |     30 |          0 |
    +--------+------------+
    3 rows in set, 14 warnings (0.00 sec)
    
    mysql> select deptno, avg(ename) from emp group by deptno;
    +--------+------------+
    | deptno | avg(ename) |
    +--------+------------+
    |     10 |          0 |
    |     20 |          0 |
    |     30 |          0 |
    +--------+------------+
    3 rows in set, 14 warnings (0.00 sec)
    
    mysql> select deptno, min(ename) from emp group by deptno;
    +--------+------------+
    | deptno | min(ename) |
    +--------+------------+
    |     10 | CLARK      |
    |     20 | ADAMS      |
    |     30 | ALLEN      |
    +--------+------------+
    3 rows in set (0.00 sec)
  3. 默认情况下,聚合函数忽略列值为NULL的行,不参与计算。ifnull函数,用于想要使列值为NULL的行也参与聚合统计,如:计算一组学生的最低数学成绩,若数学成绩math为NULL,则视为零分参与计算,select min(ifnull(math,0)) from students

    sql 复制代码
    mysql> select * from students;
    +----+-----+--------+-----------+------+
    | id | sn  | name   | qq        | math |
    +----+-----+--------+-----------+------+
    |  1 | 101 | 张伟   | 451591111 |   50 |
    |  2 | 103 | 子乔   | 451522222 |   50 |
    |  4 | 104 | 小贤   | 451593333 |   50 |
    |  5 | 105 | 一菲   | 123456789 |   50 |
    |  9 | 107 | 婉瑜   | 123123123 | NULL |
    +----+-----+--------+-----------+------+
    5 rows in set (0.00 sec)
    
    mysql> select min(math) from students;
    +-----------+
    | min(math) |
    +-----------+
    |        50 |
    +-----------+
    1 row in set (0.00 sec)
    
    mysql> select min(ifnull(math,0)) from students;
    +---------------------+
    | min(ifnull(math,0)) |
    +---------------------+
    |                   0 |
    +---------------------+
    1 row in set (0.00 sec)

6. 分组聚合查询group by

将一个"大表"拆分成多个"小表",这就是分组。对于每一个"小表",都有自己的聚合结果,这就是分组聚合。

聚合函数又称组函数,实际上就是对一个组中的某些数据作聚合操作,得出一个具体结果。上面介绍是一种特殊情况,即将整个表看作一个组,下面是将表分为多个组,对每个组进行聚合。

group by col:根据col列进行分组。

  • 显示每个部门的最低工资和平均工资(按deptno分组,group by deptno,deptno相同的成一组)

    sql 复制代码
    mysql> select deptno, min(sal), avg(sal) from emp group by deptno;
    +--------+----------+-------------+
    | deptno | min(sal) | avg(sal)    |
    +--------+----------+-------------+
    |     10 |  1300.00 | 2916.666667 |
    |     20 |   800.00 | 2175.000000 |
    |     30 |   950.00 | 1566.666667 |
    +--------+----------+-------------+
    3 rows in set (0.00 sec)

用于分组的列dept可以不显示,但是为了便于观察不同分组的聚合情况,最好还是加上。

分组聚合后的表,其中的一行,是某个组("小表")聚合组内多个数据并且经过某种运算得出的结果,每一组只有用于分组(可理解为标识该组唯一性)的列(即group by用的的列)是一定相同的,可以作为一个独立的值在一行显示出来,而其它列不一定相同,无法在同一行显示出来。

  • 显示每个部门的每种岗位的平均工资和最高工资(分组再分组,每一组的标识是部门+岗位)

    sql 复制代码
    mysql> select deptno, job, avg(sal) as 平均工资, max(sal) as 最高工资 from emp group by deptno, job;
    +--------+-----------+--------------+--------------+
    | deptno | job       | 平均工资      | 最高工资       |
    +--------+-----------+--------------+--------------+
    |     10 | CLERK     |  1300.000000 |      1300.00 |
    |     10 | MANAGER   |  2450.000000 |      2450.00 |
    |     10 | PRESIDENT |  5000.000000 |      5000.00 |
    |     20 | ANALYST   |  3000.000000 |      3000.00 |
    |     20 | CLERK     |   950.000000 |      1100.00 | 
    |     20 | MANAGER   |  2975.000000 |      2975.00 |
    |     30 | CLERK     |   950.000000 |       950.00 |
    |     30 | MANAGER   |  2850.000000 |      2850.00 |
    |     30 | SALESMAN  |  1400.000000 |      1600.00 |
    +--------+-----------+--------------+--------------+
    9 rows in set (0.00 sec)

having

having的作用是分组条件过滤havinggroup by配合使用,对分组聚合的结果进行条件过滤

  • 显示平均工资低于2000的部门和它的平均工资
sql 复制代码
mysql> select deptno, avg(sal) as 平均工资 from emp group by deptno having 平均工资 < 2000;
+--------+--------------+
| deptno | 平均工资      |
+--------+--------------+
|     30 |  1566.666667 |
+--------+--------------+
1 row in set (0.00 sec)

having和where的作用类似,但有些区别:

  1. where 在数据被分组前进行筛选,作用于行级别的数据。
  2. having 在数据被分组后进行筛选,作用于分组级别的数据。
相关推荐
长征coder24 分钟前
AWS MySQL 读写分离配置指南
mysql·云计算·aws
ladymorgana1 小时前
【docker】修改 MySQL 密码后 Navicat 仍能用原密码连接
mysql·adb·docker
PanZonghui1 小时前
Centos项目部署之安装数据库MySQL8
linux·后端·mysql
GreatSQL社区1 小时前
用systemd管理GreatSQL服务详解
数据库·mysql·greatsql
掘根1 小时前
【MySQL进阶】错误日志,二进制日志,mysql系统库
数据库·mysql
weixin_438335401 小时前
基础知识:mysql-connector-j依赖
数据库·mysql
小明铭同学2 小时前
MySQL 八股文【持续更新ing】
数据库·mysql
程序员岳焱12 小时前
Java 与 MySQL 性能优化:Java 实现百万数据分批次插入的最佳实践
后端·mysql·性能优化
梦在深巷、13 小时前
MySQL/MariaDB数据库主从复制之基于二进制日志的方式
linux·数据库·mysql·mariadb
Johny_Zhao14 小时前
Ubuntu系统安装部署Pandawiki智能知识库
linux·mysql·网络安全·信息安全·云计算·shell·yum源·系统运维·itsm·pandawiki