目录
1.CRUD
2. 增加(Create)
2.1 单行数据的全列插入
2.2 单行数据的指定列插入
2.3 多行数据的全列插入
2.4 多行数据的指定列插入
2.5 时间日期类型数据的插入
3. 查询(Retrieve)
3.1 全列查询
3.2 指定列查询
3.3 表达式查询
3.4 指定别名查询
3.5 去重查询
3.6 查询结果排序
3.6.1 升序排列:order by+列名:
3.6.2 降序排列:order by +列名+desc:
3.6.3 多列排序
3.7 条件查询
3.7.1 基本查询
3.7.2 基本查询与表达式的结合
3.7.3 比较运算符与逻辑运算符结合的条件查询
3.7.4 范围查询
3.7.5 模糊查询
3.7.6 NULL查询
3.8 分页查询
4. 修改(Update)
5. 删除(Delete)
CRUD是增加(Create),查询(Retrieve),更新(Update),删除(Delete)四个单词的首字母缩写;
mysql> show tables;
+---------------------+
| Tables_in_testdemo2 |
+---------------------+
| student |
+---------------------+
1 row in set (0.00 sec)
mysql> desc student;
+-------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| id | int(11) | YES | | NULL | |
| name | varchar(20) | YES | | NULL | |
+-------+-------------+------+-----+---------+-------+
2 rows in set (0.00 sec)
mysql> insert into student values(1, "张三");
Query OK, 1 row affected (0.03 sec)
注:(1)使用“ insert into [表名] values(值, 值...); ”进行新增或插入数据,注意值的个数、顺序、类型要与表头一致,如果不一致就会报错:
错误示例1:
mysql> insert into student values(1,2,"张三");
ERROR 1136 (21S01): Column count doesn't match value count at row 1
报错信息为:列数与值数不匹配;
错误示例2:
mysql> insert into student values("张三", 1);
ERROR 1366 (HY000): Incorrect integer value: '张三' for column 'id' at row 1
报错信息为:张三是不正确的整型值;
错误示例3:
还有可能有一种错误是数据库字符集没有正确匹配,
数据库不作任何修改默认情况下创建的数据库字符集是拉丁文字符集,不能表示中文,此时要将输入文字与数据库字符集相匹配,具体步骤为:
① 删除原数据库,② 创建新数据库并指定字符集,以testdemo2为例:
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
| testdemo1 |
| testdemo2 |
+--------------------+
6 rows in set (0.00 sec)
mysql> drop database testdemo2;
Query OK, 0 rows affected (0.07 sec)
mysql> create database testdemo2 charset utf8;
Query OK, 1 row affected, 1 warning (0.09 sec)
但是请注意,MySQL的utf8相比完全版本的utf8缺少了emoji表情,保存正常数据没有问题,但带表情就可能出错,utf8mb4是更完整的utf8;
(2)SQL没有字符类型,单引号和双引号都可以表示字符串;
mysql> create table student(id int, name varchar(20), gender varchar(5));
Query OK, 0 rows affected (0.15 sec)
mysql> desc student;
+--------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+--------+-------------+------+-----+---------+-------+
| id | int(11) | YES | | NULL | |
| name | varchar(20) | YES | | NULL | |
| gender | varchar(5) | YES | | NULL | |
+--------+-------------+------+-----+---------+-------+
3 rows in set (0.00 sec)
mysql> insert into student (name, gender) values("张三", "男");
Query OK, 1 row affected (0.07 sec)
注:(1)使用“ insert into [表名] (列名, 列名) values(值, 值...); ”指定列新增或插入数据,此时values后的值就是和values前()的内容相匹配的;
(2)想要输出插入后的结果,就需要进行查询;
mysql> insert into student values(2, "李四", "女"),(3, "王五", "男");
Query OK, 2 rows affected (0.07 sec)
Records: 2 Duplicates: 0 Warnings: 0
mysql> select* from student;
+------+------+--------+
| id | name | gender |
+------+------+--------+
| NULL | 张三 | 男 |
| 2 | 李四 | 女 |
| 3 | 王五 | 男 |
+------+------+--------+
3 rows in set (0.00 sec)
mysql> insert into student(id, name) values(5, "赵六");
Query OK, 1 row affected (0.03 sec)
mysql> select* from student;
+------+------+--------+
| id | name | gender |
+------+------+--------+
| NULL | 张三 | 男 |
| 2 | 李四 | 女 |
| 3 | 王五 | 男 |
| 5 | 赵六 | NULL |
+------+------+--------+
4 rows in set (0.00 sec)
注:(1)由于MySQL是一个“客户端服务器”结构的程序,n行数据一次插入比单行数据n次插入效率更高且成本更低,因为多行数据的一次插入只需要客户端和服务器交互一次,但一行数据的多行插入要与服务器交互多次;
插入时间时,是通过特定格式的字符来表示时间日期的:如“ 2023-02-17 21:25:00 ”:
mysql> create table homework(id int, uploadTime datetime);
Query OK, 0 rows affected (0.07 sec)
mysql> desc homework;
+------------+----------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+------------+----------+------+-----+---------+-------+
| id | int(11) | YES | | NULL | |
| uploadTime | datetime | YES | | NULL | |
+------------+----------+------+-----+---------+-------+
2 rows in set (0.00 sec)
mysql> insert into homework values(1, "2023-07-19 12:20:00");
Query OK, 1 row affected (0.05 sec)
mysql> select* from homework;
+------+---------------------+
| id | uploadTime |
+------+---------------------+
| 1 | 2023-07-19 12:20:00 |
+------+---------------------+
1 row in set (0.00 sec)
注:如果需要将该时间日期类型数据设置为当前时刻,可以使用MySQL提供的now()函数:
mysql> insert into homework values(2, now());
Query OK, 1 row affected (0.05 sec)
mysql> select* from homework;
+------+---------------------+
| id | uploadTime |
+------+---------------------+
| 1 | 2023-07-19 12:20:00 |
| 2 | 2023-07-19 14:45:21 |
+------+---------------------+
2 rows in set (0.00 sec)
全列查找即:查找整个表的所有行和所有列,上文代码示例所用查询方式就是全列查找:
mysql> select* from student;
+------+------+--------+
| id | name | gender |
+------+------+--------+
| NULL | 张三 | 男 |
| 2 | 李四 | 女 |
| 3 | 王五 | 男 |
| 5 | 赵六 | NULL |
+------+------+--------+
4 rows in set (0.00 sec)
注:(1)使用“ select* from [表名]; ”进行全列查询,*表示所有列,这种特殊含义的符号在计算机中叫做“通配符”;
(2)在服务器接收到客户端的请求后,服务器会根据请求的SQL查询保存的数据,将数据读取出来通过网络返回给客户端,返回的结果相当于是个临时表,或称为结果集,仅用于显示给客户端。
(3)select* 操作也是非常危险的,如果数据量有几亿或几十亿之大,就会瞬间吃满硬盘带宽和网络带宽,导致其他程序无法使用硬盘或网络;
mysql> select name, gender from student;
+------+--------+
| name | gender |
+------+--------+
| 张三 | 男 |
| 李四 | 女 |
| 王五 | 男 |
| 赵六 | NULL |
+------+--------+
4 rows in set (0.00 sec)
mysql> select gender, name from student;
+--------+------+
| gender | name |
+--------+------+
| 男 | 张三 |
| 女 | 李四 |
| 男 | 王五 |
| NULL | 赵六 |
+--------+------+
4 rows in set (0.00 sec)
注:(1)使用“ select 列名, 列名... from [表名] ”进行指定列查询;
在查询过程中可以作一些进行列之间简单运算:
示例1:对某一列数据进行运算操作
mysql> insert into exam_result values(1,"zhangsan",67,98,56),
-> (2,"lisi",87.5,78,77),
-> (3,"wangwu",88,98,90),
-> (4,"zhaoliu",82,84,67),
-> (5,"tianqi",55.5,85,45),
-> (6,"qianba",70,73,78.5),
-> (7,"chenjiu",75,65,30);
Query OK, 7 rows affected (0.04 sec)
Records: 7 Duplicates: 0 Warnings: 0
mysql> select* from exam_result;
+------+----------+---------+------+---------+
| id | name | chinese | math | english |
+------+----------+---------+------+---------+
| 1 | zhangsan | 67.0 | 98.0 | 56.0 |
| 2 | lisi | 87.5 | 78.0 | 77.0 |
| 3 | wangwu | 88.0 | 98.0 | 90.0 |
| 4 | zhaoliu | 82.0 | 84.0 | 67.0 |
| 5 | tianqi | 55.5 | 85.0 | 45.0 |
| 6 | qianba | 70.0 | 73.0 | 78.5 |
| 7 | chenjiu | 75.0 | 65.0 | 30.0 |
+------+----------+---------+------+---------+
7 rows in set (0.00 sec)
mysql> select name, math+10 from exam_result;
+----------+---------+
| name | math+10 |
+----------+---------+
| zhangsan | 108.0 |
| lisi | 88.0 |
| wangwu | 108.0 |
| zhaoliu | 94.0 |
| tianqi | 95.0 |
| qianba | 83.0 |
| chenjiu | 75.0 |
+----------+---------+
7 rows in set (0.00 sec)
注:(1)这样的查询方式,数据库服务器硬盘的数据并没有发生改变,此时再次查询english,结果仍然是未经运算前的数据;
这与MySQL的客户端服务器结构是一致的,服务器解析并执行客户端发出的请求后,将查询的结果从硬盘中读取出来通过网络响应还给客户端,客户端把这些数据以临时表的形式展示出来,临时表仅用于显示给客户端,与服务器的硬盘上的表没有联系;
基于以上代码,再次查看exam_result表中的name列和math列:
mysql> select name, math from exam_result;
+----------+------+
| name | math |
+----------+------+
| zhangsan | 98.0 |
| lisi | 78.0 |
| wangwu | 98.0 |
| zhaoliu | 84.0 |
| tianqi | 85.0 |
| qianba | 73.0 |
| chenjiu | 65.0 |
+----------+------+
7 rows in set (0.00 sec)
(2)创建表时设置的数据类型是原始表数据的类型,对临时表的数据不构成约束,故而:
创建的exam_result表的浮点数数据类型为decimal(3,1),但使用select name, math+10 from exam_result时,该临时表的数据的108.0是允许存在的;
示例2:多列进行运算操作
mysql> select name, chinese+math+english from exam_result;
+----------+----------------------+
| name | chinese+math+english |
+----------+----------------------+
| zhangsan | 221.0 |
| lisi | 242.5 |
| wangwu | 276.0 |
| zhaoliu | 233.0 |
| tianqi | 185.5 |
| qianba | 221.5 |
| chenjiu | 170.0 |
+----------+----------------------+
7 rows in set (0.00 sec)
基于原表中每个人的各科成绩,可以输出总成绩;
注:(1)表达式查询是列与列之间进行运算,而非行与行之间,行与行之间的运算是聚合运算;
按照表达式查询,临时表的列名与表达式是一样的,可能会不直观,所以又引出了指定别名的查询方法,使用as可以为临时表的列指定别名:
mysql> select name, chinese+math+english as total from exam_result;
+----------+-------+
| name | total |
+----------+-------+
| zhangsan | 221.0 |
| lisi | 242.5 |
| wangwu | 276.0 |
| zhaoliu | 233.0 |
| tianqi | 185.5 |
| qianba | 221.5 |
| chenjiu | 170.0 |
+----------+-------+
7 rows in set (0.00 sec)
注:as可以省略,但不建议这样写;
可以使用distinct关键字对某列数据进行去重:
(1)单列去重:
mysql> select* from exam_result;
+------+----------+---------+------+---------+
| id | name | chinese | math | english |
+------+----------+---------+------+---------+
| 1 | zhangsan | 67.0 | 98.0 | 56.0 |
| 2 | lisi | 87.5 | 78.0 | 77.0 |
| 3 | wangwu | 88.0 | 98.0 | 90.0 |
| 4 | zhaoliu | 82.0 | 84.0 | 67.0 |
| 5 | tianqi | 55.5 | 85.0 | 45.0 |
| 6 | qianba | 70.0 | 73.0 | 78.5 |
| 7 | chenjiu | 75.0 | 65.0 | 30.0 |
+------+----------+---------+------+---------+
7 rows in set (0.00 sec)
mysql> select distinct math from exam_result;
+------+
| math |
+------+
| 98.0 |
| 78.0 |
| 84.0 |
| 85.0 |
| 73.0 |
| 65.0 |
+------+
6 rows in set (0.00 sec)
(2)多列去重:distinct指定多列时,要求这些列的值都相同,才视为重复;
使用order by 子句,指定某些列进行升序或降序排列:
mysql> select* from exam_result;
+------+----------+---------+------+---------+
| id | name | chinese | math | english |
+------+----------+---------+------+---------+
| 1 | zhangsan | 67.0 | 98.0 | 56.0 |
| 2 | lisi | 87.5 | 78.0 | 77.0 |
| 3 | wangwu | 88.0 | 98.0 | 90.0 |
| 4 | zhaoliu | 82.0 | 84.0 | 67.0 |
| 5 | tianqi | 55.5 | 85.0 | 45.0 |
| 6 | qianba | 70.0 | 73.0 | 78.5 |
| 7 | chenjiu | 75.0 | 65.0 | 30.0 |
+------+----------+---------+------+---------+
7 rows in set (0.00 sec)
mysql> select* from exam_result order by math;
+------+----------+---------+------+---------+
| id | name | chinese | math | english |
+------+----------+---------+------+---------+
| 7 | chenjiu | 75.0 | 65.0 | 30.0 |
| 6 | qianba | 70.0 | 73.0 | 78.5 |
| 2 | lisi | 87.5 | 78.0 | 77.0 |
| 4 | zhaoliu | 82.0 | 84.0 | 67.0 |
| 5 | tianqi | 55.5 | 85.0 | 45.0 |
| 1 | zhangsan | 67.0 | 98.0 | 56.0 |
| 3 | wangwu | 88.0 | 98.0 | 90.0 |
+------+----------+---------+------+---------+
7 rows in set (0.00 sec)
注:(1)一个SQL如果没有指定order by,此时查询结果集的数据顺序是不可预期的,故而代码逻辑不可依赖这里的查询顺序;
(2)order by 是可以根据多个列来排序的,直接使用逗号来分割;
mysql> select* from exam_result;
+------+----------+---------+------+---------+
| id | name | chinese | math | english |
+------+----------+---------+------+---------+
| 1 | zhangsan | 67.0 | 98.0 | 56.0 |
| 2 | lisi | 87.5 | 78.0 | 77.0 |
| 3 | wangwu | 88.0 | 98.0 | 90.0 |
| 4 | zhaoliu | 82.0 | 84.0 | 67.0 |
| 5 | tianqi | 55.5 | 85.0 | 45.0 |
| 6 | qianba | 70.0 | 73.0 | 78.5 |
| 7 | chenjiu | 75.0 | 65.0 | 30.0 |
+------+----------+---------+------+---------+
7 rows in set (0.00 sec)
mysql> select* from exam_result order by math desc;
+------+----------+---------+------+---------+
| id | name | chinese | math | english |
+------+----------+---------+------+---------+
| 1 | zhangsan | 67.0 | 98.0 | 56.0 |
| 3 | wangwu | 88.0 | 98.0 | 90.0 |
| 5 | tianqi | 55.5 | 85.0 | 45.0 |
| 4 | zhaoliu | 82.0 | 84.0 | 67.0 |
| 2 | lisi | 87.5 | 78.0 | 77.0 |
| 6 | qianba | 70.0 | 73.0 | 78.5 |
| 7 | chenjiu | 75.0 | 65.0 | 30.0 |
+------+----------+---------+------+---------+
7 rows in set (0.00 sec)
注:(1)此处的desc不是description而是descend的缩写;
还可以进行多列排序,每列之间使用逗号分割,越靠前的列,其作为排序依据越关键:
mysql> select* from exam_result;
+------+----------+---------+------+---------+
| id | name | chinese | math | english |
+------+----------+---------+------+---------+
| 1 | zhangsan | 67.0 | 98.0 | 56.0 |
| 2 | lisi | 87.5 | 78.0 | 77.0 |
| 3 | wangwu | 88.0 | 98.0 | 90.0 |
| 4 | zhaoliu | 82.0 | 84.0 | 67.0 |
| 5 | tianqi | 55.5 | 85.0 | 45.0 |
| 6 | qianba | 70.0 | 73.0 | 78.5 |
| 7 | chenjiu | 75.0 | 65.0 | 30.0 |
+------+----------+---------+------+---------+
7 rows in set (0.00 sec)
mysql> select* from exam_result order by math desc, chinese desc;
+------+----------+---------+------+---------+
| id | name | chinese | math | english |
+------+----------+---------+------+---------+
| 3 | wangwu | 88.0 | 98.0 | 90.0 |
| 1 | zhangsan | 67.0 | 98.0 | 56.0 |
| 5 | tianqi | 55.5 | 85.0 | 45.0 |
| 4 | zhaoliu | 82.0 | 84.0 | 67.0 |
| 2 | lisi | 87.5 | 78.0 | 77.0 |
| 6 | qianba | 70.0 | 73.0 | 78.5 |
| 7 | chenjiu | 75.0 | 65.0 | 30.0 |
+------+----------+---------+------+---------+
7 rows in set (0.00 sec)
上文排序依据为:先按数学成绩排序,如果数学成绩相同,则使用语文成绩排名;
条件查询是指在查询的时候可以指定筛选条件,即符合条件的数据保留;
在SQL中使用where子句与下列一系列运算符表示条件,就可以完成条件查询;
(1)比较运算符:
运算符 | 说明 |
>, >=, <, <= | 大于,大于等于,小于,小于等于 |
= | 等于,NULL不安全,如NULL=NULL的结果是NULL |
<=> | 等于,NULL安全,如NULL<=>NULL的结果是TRUE(1) |
!=, <> | 不等于 |
BETWEEN a0 AND a1 | 范围匹配,[a0, a1],如果a0<=value<=a1,返回TRUE(1) |
IN(OPTION, ...) | 如果是option中的任意一个,返回TRUE |
IS NULL | 是NULL |
IS NOT NULL | 不是NULL |
LIKE | 模糊匹配,%表示任意多个(包括0个)任意字符;_表示任意一个字符 |
(2)逻辑运算符:
运算符 | 说明 |
AND | 多个条件必须都为TRUE(1),结果擦拭TRUE(1) |
OR | 任意一个条件为TRUE(1),结果为TRUE(1) |
NOT | 条件为TRUE(1),结果为FALSE(0) |
(选出英语成绩低于60的同学信息)
mysql> select* from exam_result;
+------+----------+---------+------+---------+
| id | name | chinese | math | english |
+------+----------+---------+------+---------+
| 1 | zhangsan | 67.0 | 98.0 | 56.0 |
| 2 | lisi | 87.5 | 78.0 | 77.0 |
| 3 | wangwu | 88.0 | 98.0 | 90.0 |
| 4 | zhaoliu | 82.0 | 84.0 | 67.0 |
| 5 | tianqi | 55.5 | 85.0 | 45.0 |
| 6 | qianba | 70.0 | 73.0 | 78.5 |
| 7 | chenjiu | 75.0 | 65.0 | 30.0 |
+------+----------+---------+------+---------+
7 rows in set (0.00 sec)
mysql> select* from exam_result where english<60;
+------+----------+---------+------+---------+
| id | name | chinese | math | english |
+------+----------+---------+------+---------+
| 1 | zhangsan | 67.0 | 98.0 | 56.0 |
| 5 | tianqi | 55.5 | 85.0 | 45.0 |
| 7 | chenjiu | 75.0 | 65.0 | 30.0 |
+------+----------+---------+------+---------+
3 rows in set (0.00 sec)
(选出总分成绩低于200的同学信息并输出总分)
mysql> select name, chinese+ math+ english as total from exam_result where chinese+ math+ english<200;
+---------+-------+
| name | total |
+---------+-------+
| tianqi | 185.5 |
| chenjiu | 170.0 |
+---------+-------+
2 rows in set (0.00 sec)
注意: 别名不能作为where条件:
mysql> select name, chinese+ math+ english as total from exam_result where total<200;
ERROR 1054 (42S22): Unknown column 'total' in 'where clause'
因为SQL的执行顺序并非从前往后,而是有特定的规则。
在上述代码中,执行规则为:遍历每一行->将该行数据代入where的条件中->符合条件的结果再根据select这里指定的列进行查询或计算,
在先执行where子句进行判断时,total是不存在的,此时就会发生错误;
注:条件查询其实就是遍历数据库中的表,取出每一行的数据,将数据代入条件中判断是否符合,
如果为真则记录保留,作为结果集的一部分;如果为假则跳过,判断下一行数据;
(选出语文成绩高于80且英语成绩高于80的同学信息)
mysql> select* from exam_result where chinese>80 and english>80;
+------+--------+---------+------+---------+
| id | name | chinese | math | english |
+------+--------+---------+------+---------+
| 3 | wangwu | 88.0 | 98.0 | 90.0 |
+------+--------+---------+------+---------+
1 row in set (0.00 sec)
注:如果一个where中既存在AND又存在OR,先执行AND,再执行OR;
(选出语文成绩在80到90分之间的同学)
mysql> select* from exam_result where chinese between 80 and 90;
+------+---------+---------+------+---------+
| id | name | chinese | math | english |
+------+---------+---------+------+---------+
| 2 | lisi | 87.5 | 78.0 | 77.0 |
| 3 | wangwu | 88.0 | 98.0 | 90.0 |
| 4 | zhaoliu | 82.0 | 84.0 | 67.0 |
+------+---------+---------+------+---------+
3 rows in set (0.00 sec)
注:(1)between ... and... 约定的是一个前闭后闭区间,即包含两侧边界;
(2)也可以写为:
select* from exam_result where chinese >=80 and chinese<=90;
(查询姓孙同学和姓孙两字同学的信息)
创建以下表:
mysql> select* from exam_result;
+------+--------+---------+------+---------+
| id | name | chinese | math | english |
+------+--------+---------+------+---------+
| 1 | 唐三藏 | 67.0 | 98.0 | 56.0 |
| 2 | 孙悟空 | 87.5 | 78.0 | 77.0 |
| 3 | 猪悟能 | 88.0 | 98.5 | 90.0 |
| 4 | 曹孟德 | 82.0 | 84.0 | 67.0 |
| 5 | 刘玄德 | 55.5 | 85.0 | 45.0 |
| 6 | 孙权 | 70.0 | 73.0 | 78.5 |
| 7 | 宋公明 | 75.0 | 65.0 | 30.0 |
+------+--------+---------+------+---------+
7 rows in set (0.00 sec)
基于以上表,查询姓孙同学和姓孙两字同学的信息:
mysql> select* from exam_result where name like "孙%";
+------+--------+---------+------+---------+
| id | name | chinese | math | english |
+------+--------+---------+------+---------+
| 2 | 孙悟空 | 87.5 | 78.0 | 77.0 |
| 6 | 孙权 | 70.0 | 73.0 | 78.5 |
+------+--------+---------+------+---------+
2 rows in set (0.00 sec)
mysql> select* from exam_result where name like "孙_";
+------+------+---------+------+---------+
| id | name | chinese | math | english |
+------+------+---------+------+---------+
| 6 | 孙权 | 70.0 | 73.0 | 78.5 |
+------+------+---------+------+---------+
1 row in set (0.00 sec)
注:(1)like只支持两个用法:
① 使用% 代表任意0个字符或者n个字符; ② 使用_代表任意1个字符;
(2)like相比正则表达式,支持的功能更少,因为MySQL效率较低,很容易成为性能瓶颈,模糊匹配是比较低效的写法,如果这里支持的功能更复杂,就会拖慢数据库的效率;
(查询已知性别且学号未知的同学信息)
试创建以下表:
mysql> select* from student;
+------+------+--------+
| id | name | gender |
+------+------+--------+
| NULL | 张三 | 男 |
| 2 | 李四 | 女 |
| 3 | 王五 | 男 |
| 5 | 赵六 | NULL |
+------+------+--------+
4 rows in set (0.00 sec)
基于以上表,查询已知性别且学号未知的同学信息:
mysql> select* from student where gender is not null and id is null;
+------+------+--------+
| id | name | gender |
+------+------+--------+
| NULL | 张三 | 男 |
+------+------+--------+
1 row in set (0.00 sec)
注:(1)MySQL中的null非常特殊:
① null和其他数值进行运算,结果还是null;
② null作为条件相当于false;
故而以下使用方法是错误的:
mysql> select* from exam_result;
+------+--------+---------+------+---------+
| id | name | chinese | math | english |
+------+--------+---------+------+---------+
| 1 | 唐三藏 | 67.0 | 98.0 | 56.0 |
| 2 | 孙悟空 | 87.5 | 78.0 | 77.0 |
| 3 | 猪悟能 | 88.0 | 98.5 | 90.0 |
| 4 | 曹孟德 | 82.0 | 84.0 | 67.0 |
| 5 | 刘玄德 | 55.5 | 85.0 | 45.0 |
| 6 | 孙权 | 70.0 | 73.0 | 78.5 |
| 7 | 宋公明 | 75.0 | 65.0 | 30.0 |
| 8 | 司马懿 | NULL | NULL | NULL |
+------+--------+---------+------+---------+
8 rows in set (0.00 sec)
mysql> select* from exam_result where chinese = null;
Empty set (0.00 sec)
相当于遍历到id为8的同学时, 判断null=null,结果仍然为null,即false,即输出为空;
=是null不安全的,可以使用<=>判断是否为空,也可使用is null:
mysql> select* from exam_result where chinese <=> null;
+------+--------+---------+------+---------+
| id | name | chinese | math | english |
+------+--------+---------+------+---------+
| 8 | 司马懿 | NULL | NULL | NULL |
+------+--------+---------+------+---------+
1 row in set (0.00 sec)
mysql> select* from exam_result limit 3;
+------+--------+---------+------+---------+
| id | name | chinese | math | english |
+------+--------+---------+------+---------+
| 1 | 唐三藏 | 67.0 | 98.0 | 56.0 |
| 2 | 孙悟空 | 87.5 | 78.0 | 77.0 |
| 3 | 猪悟能 | 88.0 | 98.5 | 90.0 |
+------+--------+---------+------+---------+
3 rows in set (0.00 sec)
mysql> select* from exam_result limit 3 offset 3;
+------+--------+---------+------+---------+
| id | name | chinese | math | english |
+------+--------+---------+------+---------+
| 4 | 曹孟德 | 82.0 | 84.0 | 67.0 |
| 5 | 刘玄德 | 55.5 | 85.0 | 45.0 |
| 6 | 孙权 | 70.0 | 73.0 | 78.5 |
+------+--------+---------+------+---------+
3 rows in set (0.00 sec)
mysql> select* from exam_result limit 3 offset 6;
+------+--------+---------+------+---------+
| id | name | chinese | math | english |
+------+--------+---------+------+---------+
| 7 | 宋公明 | 75.0 | 65.0 | 30.0 |
| 8 | 司马懿 | NULL | NULL | NULL |
+------+--------+---------+------+---------+
2 rows in set (0.00 sec)
注:(1)使用limit关键字限制查询结果个数上限;
(2)limit还可以搭配offset使用,声明从哪一条开始查询,默认从0开始;
(3)limit可以搭配以前的别名、排序等等进行使用,比如查询总分前三的同学:
mysql> select id, name, chinese+math+english as total from exam_result
-> order by total desc limit 3;
+------+--------+-------+
| id | name | total |
+------+--------+-------+
| 3 | 猪悟能 | 276.5 |
| 2 | 孙悟空 | 242.5 |
| 4 | 曹孟德 | 233.0 |
+------+--------+-------+
3 rows in set (0.00 sec)
注:where中不可使用同句的别名,是因为where先于别名计算执行,但order by可以使用同句的别名,是因为order by 的执行时间要比创建别名的时间更晚;
基于以下表:
mysql> select* from exam_result;
+------+--------+---------+------+---------+
| id | name | chinese | math | english |
+------+--------+---------+------+---------+
| 1 | 唐三藏 | 67.0 | 98.0 | 56.0 |
| 2 | 孙悟空 | 87.5 | 80.0 | 77.0 |
| 3 | 猪悟能 | 88.0 | 98.5 | 90.0 |
| 4 | 曹孟德 | 70.0 | 80.0 | 67.0 |
| 5 | 刘玄德 | 55.5 | 85.0 | 45.0 |
| 6 | 孙权 | 70.0 | 73.0 | 78.5 |
| 7 | 宋公明 | 75.0 | 65.0 | 30.0 |
| 8 | 司马懿 | NULL | NULL | NULL |
+------+--------+---------+------+---------+
8 rows in set (0.00 sec)
为总分倒数前三名的同学数学成绩加十分:
mysql> select name,chinese+math+english as total from exam_result order by total desc;
+--------+-------+
| name | total |
+--------+-------+
| 猪悟能 | 276.5 |
| 孙悟空 | 244.5 |
| 孙权 | 221.5 |
| 唐三藏 | 221.0 |
| 曹孟德 | 217.0 |
| 刘玄德 | 185.5 |
| 宋公明 | 170.0 |
| 司马懿 | NULL |
+--------+-------+
8 rows in set (0.00 sec)
mysql> update exam_result set math=math+10 order by chinese+math+english limit 3;
Query OK, 2 rows affected (0.07 sec)
Rows matched: 3 Changed: 2 Warnings: 0
mysql> select* from exam_result;
+------+--------+---------+------+---------+
| id | name | chinese | math | english |
+------+--------+---------+------+---------+
| 1 | 唐三藏 | 67.0 | 98.0 | 56.0 |
| 2 | 孙悟空 | 87.5 | 80.0 | 77.0 |
| 3 | 猪悟能 | 88.0 | 98.5 | 90.0 |
| 4 | 曹孟德 | 70.0 | 80.0 | 67.0 |
| 5 | 刘玄德 | 55.5 | 95.0 | 45.0 |
| 6 | 孙权 | 70.0 | 73.0 | 78.5 |
| 7 | 宋公明 | 75.0 | 75.0 | 30.0 |
| 8 | 司马懿 | NULL | NULL | NULL |
+------+--------+---------+------+---------+
8 rows in set (0.00 sec)
注:(1)使用“ update [表名] set 列名=值, 列名=值... where 条件 ”进行修改,可以搭配order by和limit进行使用,当修改范围是全部数据时,不写条件即可;
(2)null在排序时会被视为最小的值;
(3)SQL不支持+=表示,math=math+10不能写为math+=10;
(4)更新的数据是操作硬盘数据的,故而当修改后的数据不符合表数据类型时,就会报错,且修改无效;
(5)update操作也非常危险,使用时也许谨慎;
mysql> select* from exam_result;
+------+--------+---------+------+---------+
| id | name | chinese | math | english |
+------+--------+---------+------+---------+
| 1 | 唐三藏 | 33.5 | 98.0 | 56.0 |
| 3 | 猪悟能 | 44.0 | 98.5 | 90.0 |
| 4 | 曹孟德 | 35.0 | 80.0 | 67.0 |
| 5 | 刘玄德 | 27.8 | 95.0 | 45.0 |
| 7 | 宋公明 | 37.5 | 75.0 | 30.0 |
+------+--------+---------+------+---------+
5 rows in set (0.00 sec)
注:(1)使用“ delete from [表名] where 条件 ”删除记录(一行);
(2)如果没有写条件,即没有where子句,delete句基本相当于删表,表仍存在但数据不存在了;
(删表是表与数据均被删除了)
(3)truncate 也可清空表的内容,只是delete是一行一行删,效率较低,truncate是一次性删除;
(4)如果执行SQL的时间很长,随时可以使用ctrl+c取消;