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 在数据被分组后进行筛选,作用于分组级别的数据。
相关推荐
Sunyanhui12 小时前
牛客网 SQL36查找后排序
数据库·sql·mysql
老王笔记2 小时前
MHA binlog server
数据库·mysql
2401_871213304 小时前
mysql高阶语句
数据库·mysql
山山而川粤6 小时前
网络安全宣传系统|Java|SSM|JSP|
java·开发语言·后端·学习·mysql
_汤姆大叔6 小时前
MySQL 高级操作全解析
数据库·mysql
呼啦啦啦啦啦啦啦啦8 小时前
【MySQL篇】聚合查询,联合查询
数据库·mysql
今天不coding8 小时前
MySQL体系架构
数据库·mysql·体系架构·网络连接层·服务层·存储引擎层·系统文件层
奥顺互联V11 小时前
一次性部署:使用Docker部署PHP应用
大数据·mysql·开源·php
小黄人软件11 小时前
20241220流水的日报 mysql的between可以用于字符串 sql 所有老日期的,保留最新日期
数据库·sql·mysql
无为之士11 小时前
Linux自动备份Mysql数据库
linux·数据库·mysql