0


MySQL所有基本操作详解

文章目录

一.MySQL的基本操作

首先sql操作中的关键字的是大小写不敏感的,create 和CREATE是一样的。

1.库操作

1.1 查看数据库

语法:

showdatabases;

示例:
在这里插入图片描述

  1. show 和databases 之间有一个或者多个空格
  2. 注意是databases而不是database
  3. 结尾分号是英文形式,分号在SQL中是表示一行执行+
  4. 代码的,如果语句后面么有分号,那么默认是要一句代码分多行来写(如下图)

在这里插入图片描述

  1. 下图中是每次执行完一个sql语句之后,会得到的一个反馈,反馈会告诉我们,当前结果有多少行记录,以及消耗了多少时间。在下图中set表示集合,所以意思就是在当前集合里有四行,执行共花费0.01秒(sec = second 秒)。有时会显示0.00 sec.,这表示小于10毫秒,所以不显示。

在这里插入图片描述

1.2 创建数据库

语法:

CREATEDATABASE[IFNOTEXISTS] 数据库名称 [create_specification [, 
create_specification]...]
create_specification:
 [DEFAULT]CHARACTERSET charset_name
 [DEFAULT]COLLATE collation_name
  1. 大写的表示关键字
  2. [] 是可选项
  3. CHARACTER SET: 指定数据库采用的字符集
  4. COLLATE: 指定数据库字符集的校验规则
  5. 数据库名字可由数字,字母,下划线组成,数字不能开头(和java变量名一样),名字也不能是sql关键字(例如 show 、database)在这里插入图片描述
  6. 如果就是想拿关键词作为数据库名,可以使用反引号`把数据库名引起来。在这里插入图片描述 这里面的错误是ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ‘databese’ at line 1。

syntax是句法的意思,就理解成语法就行。manual——手册
对我们比较重要是最后

near 'databese' at line 1

这一句,表面错误在第一行的database附近

  1. 创建数据库的时候可以指定字符集和校验规则 当我们创建数据库没有指定字符集和校验规则时,系统使用默认字符集:utf8,校验规则是:utf8_ general_ ci注意:MySQL的utf8编码不是真正的utf8,没有包含某些复杂的中文字符。MySQL真正的utf8是使用utf8mb4,建议大家都使用utf8mb4

示例

1.创建名为db_test1的数据库

CREATEDATABASE db_test1;

2.如果系统没有db_test2的数据库,则创建一个名叫db_test2的数据库,如果有则不创建

CREATEDATABASEIFNOTEXISTS db_test2;

3.如果系统没有db_test的数据库,则创建一个使用utf8mb4字符集的db_test数据库,如果有则不创建

CREATEDATABASEIFNOTEXISTS db_test CHARACTERSET utf8mb4;

1.3 使用数据库

use 数据库名;

示例
在这里插入图片描述
使用该数据库后会有相应的提示,表明数据库已经切换了。

1.4 删除数据库

语法:

DROPDATABASE[IFEXISTS] db_name;

删除操作是非常危险的!一旦删除,数据就没了,难以恢复。
数据库删除以后,内部看不到对应的数据库,里边的表和数据全部被删除

示例

dropdatabaseifexists db_test1;dropdatabaseifexists db_test2;

如果database 里有db_test1表就删除database.

2.表操作

需要操作数据库中的表时,需要先使用该数据库

2.1 创建表

语法:

CREATETABLE table_name (
    field1 datatype,
    field2 datatype,
    field3 datatype
);

示例1:

create table stu_test ( 
   id int,
   name varchar(20) comment '姓名',
   password varchar(50) comment '密码', 
   age int,
   sex varchar(1),
   birthday timestamp, 
   amout decimal(13,2), 
   resume text
);

在这里插入图片描述

  1. comment 相当于注释,这个不太好用,只能在创建表的时候使用,所以一般来说我们更推荐使用#或者 – 来表示注释

在这里插入图片描述

2.2 查看数据库中的表结构

语法:

use 数据库名;desc 表名;

示例:

desc stu_test;

在这里插入图片描述

  1. desc是describe的缩写。
  2. 查看结果经常会有int(11),这表示这一列哭护短查询显示的时候最多显示11个字符。这只是显示宽度,这与实际存储是没有关系的。
  3. NULL这一列表示的是否可以为空,如果是YES表示可以。
  4. Default 表示默认值。

2.3删除数据库中的表结构

语法:

use database_name;droptable 表名;

2.4查询某个数据库内的所有表名

语法:

use database_name;showtables;

3.SQL中的数据类型

3.1数值类型

在这里插入图片描述

  1. 数值类型可以指定为无符号(unsigned),表示不取负数。
  2. 对于整型类型的范围:有符号范围:-2^(类型字节数8-1)到2^(类型字节数8-1)-1,如int是4字节,就是-2^31到2^31-1;无符号范围:0到2^(类型字节数*8)-1,如int就是2^32-1。
  3. 在设计的时候尽量不使用unsigned,对于int类型可能存放不下的数据,int unsigned同样可能存放不下,与其如此,还不如设计时,将int类型提升为bigint类型。
  4. BIT常用来表示二进制数字串。
  5. DOUBLE(3,1)表示三位有效数字,小数位数位为1位,所以10.2合法,10.20就不合法了。

DECIMA的进一步说明
FLOAT和DOUBLE有一个很严重的问题,表示有些数据的时候,不能精确表示(存在误差),我们都知道FLOAT,DOUBLE在底层是通过多少位的底数多少位指数这种形式去表示数据的,这样带来的好处是计算速度快,存储空间小,但是会有误差。所以此时SQL提供DECIMAL(英文原意是十进制)来保存精确小数,而其底层的保存方式类型与字符串。

3.2字符串类型

在这里插入图片描述

  1. VACHAR是一个可变字符串,SIZE可以指定最大长度,单位是“字符”,所以VACHAR(10)如果表示名字的话,一个名字最多有可以存十个字,而不是五个字。同时VACHAR(10)也并不是在一开始就占10个字符的存储空间,这是动态变化的。
  2. BLOB 存储的是二进制串,注意与BIT区别,BIT最多存64个二进制数,BLOB更长。比如我要存一个小一些的图片或者音频文件,就可以使用BLOB(大概64Kb)。

3.3日期类型

在这里插入图片描述

  1. TIMESTAMP是时间戳

4.MySQL的增删改查

CRUD 增删改查(Create(增) Restrieve(查) Updata(改) Delete(删除));

4.1新增插入数据

先创建一个student表

mysql>createdatabase base1  characterset utf8mb4;;
Query OK,1row affected (0.00 sec)
mysql>use base1;Database changed
mysql>DROPTABLEIFEXISTS student;
Query OK,0rows affected,1 warning (0.00 sec)

mysql>CREATETABLE student (->     id INTNOTNULL,->     sn INT,->     name VARCHAR(20),->     qq_mail VARCHAR(20)->);
mysql>desc student;+---------+-------------+------+-----+---------+-------+| Field   |Type|Null|Key|Default| Extra |+---------+-------------+------+-----+---------+-------+| id      |int(11)|NO||NULL||| sn      |int(11)| YES  ||NULL||| name    |varchar(20)| YES  ||NULL||| qq_mail |varchar(20)| YES  ||NULL||+---------+-------------+------+-----+---------+-------+4rowsinset(0.00 sec)
Query OK,0rows affected (0.02 sec)

4.1.1基础的插入

insert[into] 表名 values[列名](值1,值2,值3.....);

实例

mysql>insertinto student values(123,4456,'张三','[email protected]');
Query OK,1row affected (0.00 sec)
mysql>insert student (id,sn,name,qq_mail)values(123,4456,'张三','[email protected]');
Query OK,1row affected (0.00 sec)

注意

  1. SQL没有字符类型,所以‘’ ""都是表示字符串类型。
  2. 假如遇到这种错误Incorrect string value: '\xE5\xBC\xA0\xE4\xB8\x89' for column 'name' at row 1显示的是不正确是字符值,往往可能是表格字符集的问题,需要将整个数据库都删除,去重新建立数据库和表格,并且一定要在创建数据库时指定字符集为utf8mb4(utf8mb4比utf8更加完整,多了对emoji表情的编码)。
  3. insert into里面into可以省略

4.1.2指定列的的插入

insert[into] 表名 (列名1,列名2,列名3......)values(值1,值2,值3,......)

示例:

mysql>insert student(id,qq_mail)values(213,'[email protected]');
Query OK,1row affected (0.00 sec)

注意:

  1. 在前面的表结构定义里面定义了id INT NOT NULL,所以id不能为空,所以id是不能系统默认创建的

结果

mysql>select*from student;+-----+------+--------+---------------+| id  | sn   | name   | qq_mail       |+-----+------+--------+---------------+|123|4456| 张三   |[email protected]||123|4456| 张三   |[email protected]||213|NULL|NULL|[email protected]|+-----+------+--------+---------------+3rowsinset(0.00 sec)

4.1.3多次数据的的插入

示例:

mysql>insertinto student values(1,1,"李四","[email protected]"),(2,2,"李四","[email protected]");

结果

mysql>select*from student;+-----+------+--------+---------------+| id  | sn   | name   | qq_mail       |+-----+------+--------+---------------+|123|4456| 张三   |[email protected]||123|4456| 张三   |[email protected]||213|NULL|NULL|[email protected]||1|1| 李四   |[email protected]||2|2| 李四   |[email protected]|+-----+------+--------+---------------+5rowsinset(0.00 sec)
  1. 一次插入N个记录是比一次插入一个记录,分N次插入效率要高,因为MySQL是c/s模式,每次请求都是需要客户端和服务器交互一次的。前者交互了一次,后者交互了多次。

4.1.4时间日期类型的插入

插入时间是通过特定的时间日期来表示时间日期的.
形如
‘2023-02-17 21:25:20’

示例

mysql>createtable homework(id int,createTime datetime);
Query OK,0rows affected (0.03 sec)
mysql>insertinto homework values(1,'2023-12-25 18:32:16');
Query OK,1row affected (0.00 sec)
mysql>select*from homework;+------+---------------------+| id   | createTime          |+------+---------------------+|1|2023-12-2518:32:16|+------+---------------------+1rowinset(0.00 sec)

同时SQL还提供now()函数来返回当前时间。
示例:

mysql>insertinto homework values(2,now());
Query OK,1row affected (0.00 sec)

mysql>select*from homework;+------+---------------------+| id   | createTime          |+------+---------------------+|1|2023-12-2518:32:16||2|2023-06-0212:04:26|+------+---------------------+2rowsinset(0.00 sec)

4.2查询数据SELECT

4.2.1全列查找

select*from 表名

在实际操作中执行select * 是非常危险的,因为实际项目中的数据量是非常大的,如果数据全部从服务器读取到客户端,数据带宽会拥堵。

4.2.2指定列查找

select 列名,列名 from 表名;

示例:

mysql>select id,name from student;+-----+--------+| id  | name   |+-----+--------+|123| 张三   ||123| 张三   ||213|NULL||1| 李四   ||2| 李四   |+-----+--------+5rowsinset(0.00 sec)

4.2.3 查询可以是表达式

示例:

先来创建一个考试成绩表

mysql>DROPTABLEIFEXISTS exam_result;
Query OK,0rows affected,1 warning (0.00 sec)

mysql>CREATETABLE exam_result (->     id INT,->     name VARCHAR(20),->     chinese DECIMAL(3,1),->     math DECIMAL(3,1),->     english DECIMAL(3,1)->);
Query OK,0rows affected (0.03 sec)

mysql>-- 插入测试数据
mysql>INSERTINTO exam_result (id,name, chinese, math, english)VALUES->(1,'唐三藏',67,98,56),->(2,'孙悟空',87.5,78,77),->(3,'猪悟能',88,98.5,90),->(4,'曹孟德',82,84,67),->(5,'刘玄德',55.5,85,45),->(6,'孙权',70,73,78.5),->(7,'宋公明',75,65,30);
Query OK,7rows affected (0.01 sec)
Records: 7  Duplicates: 0Warnings: 0

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|+------+-----------+---------+------+---------+7rowsinset(0.00 sec)

我们可以查询所有人数学成绩+10后的结果

mysql>-- 查询所有人的数学成绩+10分的结果
mysql>select math+10from exam_result;+---------+| math+10|+---------+|108.0||88.0||108.5||94.0||95.0||83.0||75.0|+---------+7rowsinset(0.00 sec)

但是注意:经过上述这样的查询,数据库服务器硬盘里面的数据是没有变化的。因为mysql是C/S模式,用户在客户端输入的sql,通过请求发送给服务器,服务器在解析并执行sql把查询结果从硬盘里读取出来,通过网络响应还给客户端,客户端把这些数据以临时表的形式显示出来。
其实细心的同学可以发现实际在定义

exam_result

math DECIMAL(3,1),

也就是说math这一列的数据应该是三个有效数字,且小数点后一位,但是math+10不难发现,这里第一行就是108.0这是因为这里的表是临时表

还可以将多个列放在一起计算
比如查询每个同学的平均成绩

mysql>select name,(math+chinese+english)/3from exam_result;+-----------+--------------------------+| name      |(math+chinese+english)/3|+-----------+--------------------------+| 唐三藏    |73.66667|| 孙悟空    |80.83333|| 猪悟能    |92.16667|| 曹孟德    |77.66667|| 刘玄德    |61.83333|| 孙权      |73.83333|| 宋公明    |56.66667|+-----------+--------------------------+7rowsinset(0.00 sec)

4.2.4指定别名

为查询结果中的列指定别名,表示返回的结果集中,以别名作为该列的名称

SELECT 表达式 [AS] 别名 [...]FROM table_name;

示例:

mysql>SELECT id, name,(chinese + math + english)/3as 平均分 FROM exam_result;+------+-----------+-----------+| id   | name      | 平均分    |+------+-----------+-----------+|1| 唐三藏    |73.66667||2| 孙悟空    |80.83333||3| 猪悟能    |92.16667||4| 曹孟德    |77.66667||5| 刘玄德    |61.83333||6| 孙权      |73.83333||7| 宋公明    |56.66667|+------+-----------+-----------+7rowsinset(0.00 sec)

4.3去重DISTINCT

mysql>selectdistinct math from exam_result;+------+| math |+------+|98.0||78.0||98.5||84.0||85.0||73.0||65.0|+------+7rowsinset(0.00 sec)

distinct 也可以实现多列的去重,但是只有每列的元素值都是相同的,才会去掉,有一列不同是sql认为是不可以去重的。
此外,下面这种写法也不对

mysql>select name,(distinct mat)h from exam_result;-- 错误
ERROR 1064(42000): You have an error in your SQL syntax;check the manual that corresponds to your MySQL server version for the right syntax touse near 'distinct mat)h from exam_result' at line 1
mysql>select name,distinct math from exam_result;-- 错误
ERROR 1064(42000): You have an error in your SQL syntax;check the manual that corresponds to your MySQL server version for the right syntax touse near 'distinct math from exam_result' at line 1

4.4 查询结果排序ORDER BY

4.4.1order by 子句

语法:

-- ASC 为升序(从小到大)-- DESC 为降序(从大到小)-- 默认为 ASCSELECT...FROM table_name [WHERE...]ORDERBYcolumn[ASC|DESC],[...];

示例:

mysql>select*from exam_result orderby math asc;+------+-----------+---------+------+---------+| id   | name      | chinese | math | english |+------+-----------+---------+------+---------+|7| 宋公明    |75.0|65.0|30.0||6| 孙权      |70.0|73.0|78.5||2| 孙悟空    |87.5|78.0|77.0||4| 曹孟德    |82.0|84.0|67.0||5| 刘玄德    |55.5|85.0|45.0||1| 唐三藏    |67.0|98.0|56.0||3| 猪悟能    |88.0|98.5|90.0|+------+-----------+---------+------+---------+7rowsinset(0.00 sec)

注意:

  1. 对于mySql而言,当我们没有指定order by (查询顺序)的人时候,此时显示的查询数据是顺序是不可预期的,代码的逻辑是不能依赖于此的。
  2. NULL 数据排序,视为比任何值都小,升序出现在最上面,降序出现在最下面。

4.4.2使用表达式及别名排序

mysql>select*,(math+chinese+english)as 总分 from exam_result orderby math desc;+------+-----------+---------+------+---------+--------+| id   | name      | chinese | math | english | 总分   |+------+-----------+---------+------+---------+--------+|3| 猪悟能    |88.0|98.5|90.0|276.5||1| 唐三藏    |67.0|98.0|56.0|221.0||5| 刘玄德    |55.5|85.0|45.0|185.5||4| 曹孟德    |82.0|84.0|67.0|233.0||2| 孙悟空    |87.5|78.0|77.0|242.5||6| 孙权      |70.0|73.0|78.5|221.5||7| 宋公明    |75.0|65.0|30.0|170.0|+------+-----------+---------+------+---------+--------+7rowsinset(0.00 sec)

mysql>select*,(math+chinese+english)as 总分 from exam_result orderby 总分 desc;+------+-----------+---------+------+---------+--------+| id   | name      | chinese | math | english | 总分   |+------+-----------+---------+------+---------+--------+|3| 猪悟能    |88.0|98.5|90.0|276.5||2| 孙悟空    |87.5|78.0|77.0|242.5||4| 曹孟德    |82.0|84.0|67.0|233.0||6| 孙权      |70.0|73.0|78.5|221.5||1| 唐三藏    |67.0|98.0|56.0|221.0||5| 刘玄德    |55.5|85.0|45.0|185.5||7| 宋公明    |75.0|65.0|30.0|170.0|+------+-----------+---------+------+---------+--------+7rowsinset(0.00 sec)

4.4.3可以对多个字段进行排序,排序优先级随书写顺序

示例:

mysql>select*from exam_result orderby math asc,chinese desc,english asc;+------+-----------+---------+------+---------+| id   | name      | chinese | math | english |+------+-----------+---------+------+---------+|7| 宋公明    |75.0|65.0|30.0||6| 孙权      |70.0|73.0|78.5||2| 孙悟空    |87.5|78.0|77.0||4| 曹孟德    |82.0|84.0|67.0||5| 刘玄德    |55.5|85.0|45.0||1| 唐三藏    |67.0|98.0|56.0||3| 猪悟能    |88.0|98.5|90.0|+------+-----------+---------+------+---------+7rowsinset(0.00 sec)

4.5条件查询WHERE

比较运算符
在这里插入图片描述
逻辑运算符
在这里插入图片描述

注意:

  1. WHERE条件可以使用表达式,但不能使用别名。
  2. AND的优先级高于OR,在同时使用时,需要使用小括号()包裹优先执行的部分

4.5.1比较运算

示例:

  1. 查询英语成绩小于60的同学信息
mysql>select*from exam_result where english <60;+------+-----------+---------+------+---------+| id   | name      | chinese | math | english |+------+-----------+---------+------+---------+|1| 唐三藏    |67.0|98.0|56.0||5| 刘玄德    |55.5|85.0|45.0||7| 宋公明    |75.0|65.0|30.0|+------+-----------+---------+------+---------+3rowsinset(0.00 sec)

注:这行代码的底层是这样的,针对数据库的表,进行遍历,取出每一行的数据,把数据带入到条件中,看是否满足条件,如果为真就保留,如果为假,就不保留。

  1. 查询语文成绩好于英语成绩的同学
mysql>select name,english,chinese from exam_result where english < chinese;+-----------+---------+---------+| name      | english | chinese |+-----------+---------+---------+| 唐三藏    |56.0|67.0|| 孙悟空    |77.0|87.5|| 曹孟德    |67.0|82.0|| 刘玄德    |45.0|55.5|| 宋公明    |30.0|75.0|+-----------+---------+---------+5rowsinset(0.00 sec)
  1. 查询总分在 200 分以下的同学
mysql>select*from exam_result where english+chinese+math >200;+------+-----------+---------+------+---------+| 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||6| 孙权      |70.0|73.0|78.5|+------+-----------+---------+------+---------+5rowsinset(0.00 sec)

注意
看下面的代码

mysql>select name,chinese+math+english as 总分 from exam_result where 总分 >200;
ERROR 1054(42S22): Unknown column'总分'in'where clause'

别名是不可以作为where条件的,这和sql的执行顺序有关,本身也是sql语法规定。上述代码的执行过程是:
1.遍历每一行;
2.把这一行带入到where的条件里去;
3.符合条件的结果,在根据select这里指定的列进行查询、计算。

但是order by 这个关键字是可以的

mysql>select name,chinese+math+english as 总分 from exam_result orderby 总分 ;+-----------+--------+| name      | 总分   |+-----------+--------+| 宋公明    |170.0|| 刘玄德    |185.5|| 唐三藏    |221.0|| 孙权      |221.5|| 曹孟德    |233.0|| 孙悟空    |242.5|| 猪悟能    |276.5|+-----------+--------+7rowsinset(0.00 sec)

4.5.2逻辑运算

示例:

mysql>-- 查询语文成绩大于80分,且英语成绩大于80分的同学
mysql>SELECT*FROM exam_result WHERE chinese >80and english >80;+------+-----------+---------+------+---------+| id   | name      | chinese | math | english |+------+-----------+---------+------+---------+|3| 猪悟能    |88.0|98.5|90.0|+------+-----------+---------+------+---------+1rowinset(0.00 sec)

mysql>-- 查询语文成绩大于80分,或英语成绩大于80分的同学
mysql>SELECT*FROM exam_result WHERE chinese >80or english >80;+------+-----------+---------+------+---------+| id   | name      | chinese | math | english |+------+-----------+---------+------+---------+|2| 孙悟空    |87.5|78.0|77.0||3| 猪悟能    |88.0|98.5|90.0||4| 曹孟德    |82.0|84.0|67.0|+------+-----------+---------+------+---------+3rowsinset(0.00 sec)
mysql>-- 观察AND 和 OR 的优先级:
mysql>SELECT*FROM exam_result WHERE chinese >80or math>70and english >70;+------+-----------+---------+------+---------+| id   | name      | chinese | math | english |+------+-----------+---------+------+---------+|2| 孙悟空    |87.5|78.0|77.0||3| 猪悟能    |88.0|98.5|90.0||4| 曹孟德    |82.0|84.0|67.0||6| 孙权      |70.0|73.0|78.5|+------+-----------+---------+------+---------+4rowsinset(0.00 sec)

mysql>SELECT*FROM exam_result WHERE(chinese >80or math>70)and english >70;+------+-----------+---------+------+---------+| id   | name      | chinese | math | english |+------+-----------+---------+------+---------+|2| 孙悟空    |87.5|78.0|77.0||3| 猪悟能    |88.0|98.5|90.0||6| 孙权      |70.0|73.0|78.5|+------+-----------+---------+------+---------+3rowsinset(0.00 sec)

AND的优先级高于OR,在同时使用时,需要使用小括号()包裹优先执行的部分.

4.5.3between and

示例:

mysql>-- 查询语文成绩在 [80, 90] 分的同学及语文成绩
mysql>SELECT name, chinese FROM exam_result WHERE chinese BETWEEN80AND90;+-----------+---------+| name      | chinese |+-----------+---------+| 孙悟空    |87.5|| 猪悟能    |88.0|| 曹孟德    |82.0|+-----------+---------+3rowsinset(0.00 sec)

mysql>-- 使用 AND 也可以实现
mysql>SELECT name, chinese FROM exam_result WHERE chinese >=80AND chinese
    -><=90;+-----------+---------+| name      | chinese |+-----------+---------+| 孙悟空    |87.5|| 猪悟能    |88.0|| 曹孟德    |82.0|+-----------+---------+3rowsinset(0.00 sec)

4.5.4 in

示例:

mysql>-- 查询数学成绩是 58 或者 59 或者 98 或者 99 分的同学及数学成绩
mysql>SELECT name, math FROM exam_result WHERE math IN(58,59,98,99);+-----------+------+| name      | math |+-----------+------+| 唐三藏    |98.0|+-----------+------+1rowinset(0.00 sec)

mysql>-- 使用 OR 也可以实现
mysql>SELECT name, math FROM exam_result WHERE math =58OR math =59OR math
    ->=98OR math =99;+-----------+------+| name      | math |+-----------+------+| 唐三藏    |98.0|+-----------+------+1rowinset(0.00 sec)

4.5.5模糊查询:LIKE

like相对于正则表达式只支持两种用法

  1. 使用%代表任意N个字符(包括0个字符);
  2. 使用_代表任意一个字符。

示例:

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|+------+-----------+---------+------+---------+2rowsinset(0.00 sec)
mysql>select*from exam_result where name like'孙_';+------+--------+---------+------+---------+| id   | name   | chinese | math | english |+------+--------+---------+------+---------+|6| 孙权   |70.0|73.0|78.5|+------+--------+---------+------+---------+1rowinset(0.00 sec)

4.5.6NULL 的查询:IS [NOT] NULL

在使用null作为查询条件即删选出某列为空的数据的时候可以使用 is null 和< = > null,这样的语句,但是此时要注意 = null、与< = >的区别

示例:

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||1| 贾宝玉 |NULL|NULL|NULL|+------+--------+---------+------+---------+8rowsinset(0.00 sec)

mysql>select*from exam_result where chinese =null;
Empty set(0.00 sec)
mysql>select*from exam_result where chinese <=>null;+------+--------+---------+------+---------+| id   | name   | chinese | math | english |+------+--------+---------+------+---------+|1| 贾宝玉 |NULL|NULL|NULL|+------+--------+---------+------+---------+1rowinset(0.00 sec)

mysql>select*from exam_result where chinese isnotnull;+------+--------+---------+------+---------+| 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|+------+--------+---------+------+---------+7rowsinset(0.00 sec)

注意

select * from exam_result where Chinese = null

执行后并不会返回Chinese列等于null的行,这是因为chinese =null 执行成功后返回的就是null也就是false。也就是默认查询条件不成立,所以根本就不会筛选。

4.5分页查询LIMIT

语法:

-- 起始下标为 0-- 从 0 开始,筛选 n 条结果SELECT...FROM table_name [WHERE...][ORDERBY...]LIMIT n;-- 从 s 开始,筛选 n 条结果SELECT...FROM table_name [WHERE...][ORDERBY...]LIMIT s, n;-- 从 s 开始,筛选 n 条结果,比第二种用法更明确,建议使用SELECT...FROM table_name [WHERE...][ORDERBY...]LIMIT n OFFSET s;

示例:

mysql>select*from exam_result limit3;+------+--------+---------+------+---------+| 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|+------+--------+---------+------+---------+3rowsinset(0.00 sec)

mysql>select*from exam_result limit3offset2;+------+--------+---------+------+---------+| id   | name   | chinese | math | english |+------+--------+---------+------+---------+|3| 猪悟能 |88.0|98.5|90.0||4| 曹孟德 |82.0|84.0|67.0||5| 刘玄德 |55.5|85.0|45.0|+------+--------+---------+------+---------+3rowsinset(0.00 sec)

mysql>select*from exam_result limit3,2;+------+--------+---------+------+---------+| id   | name   | chinese | math | english |+------+--------+---------+------+---------+|4| 曹孟德 |82.0|84.0|67.0||5| 刘玄德 |55.5|85.0|45.0|+------+--------+---------+------+---------+2rowsinset(0.00 sec)

注意:

limit s,n

limit n offset s

这里面的s n 的顺序是相反的。s表示从哪开始显示,n表示显示多少行。

limit语句常常和其他查询条件语句一起用达到组合效果

示例
寻找总分前三名的学生

mysql>select id,name,chinese+math+english as 总分 from exam_result orderby 总分 desclimit3;+------+--------+-------+| id   | name   | 总分  |+------+--------+-------+|3| 猪悟能 |276.5||2| 孙悟空 |242.5||4| 曹孟德 |233.0|+------+--------+-------+3rowsinset(0.00 sec)

4.6 修改语句UPDATE

语法:

UPDATE table_name SET 列名1= 数值1[, 列名2= 数值2...][WHERE...][ORDERBY...][LIMIT...]

示例:

mysql>-- 将孙悟空的数学成绩变更为80分
mysql>update exam_result set math =10where name ="孙悟空";
Query OK,1row affected (0.00 sec)Rowsmatched: 1  Changed: 1Warnings: 0

mysql>-- 将曹孟德同学的数学成绩变更为 60 分,语文成绩变更为 70 分
mysql>update exam_result set math =60,chinese =70where name ="曹孟德";
Query OK,1row affected (0.00 sec)Rowsmatched: 1  Changed: 1Warnings: 0

mysql>-- 将总成绩倒数前三的 3 位同学的数学成绩加上 30 分
mysql>update exam_result set math = math+30orderby math+chinese+english limit3;
Query OK,2rows affected (0.01 sec)Rowsmatched: 3  Changed: 2Warnings: 0

这里有几个点需要注意一下,

  1. null 与数值运算的时候返回值依旧为null ,比如在这里面,将总成绩倒数前三的 3 位同学的数学成绩加上 30 分,这里面总成绩倒数的第一名是贾宝玉 math Chinese English 全部是null ,在执行完这一句后并不会全部变成30,而是依旧是null,这是因为 null +10 = null。
  2. update 更改数据如果超出既有类型的范围,那么直接会报错并且并不会更改
  3. math = math +10;在SQL中并不支持简写为mate+= 10;

4.7删除DELETE

语法

DELETEFROM  table_name [WHERE...][ORDERBY ...][LIMIT...]

示例

mysql>-- 删除孙悟空同学的考试成绩
mysql>deletefrom exam_result where name ="孙悟空";
Query OK,1row affected (0.01 sec)

mysql>-- 删除姓孙的同学的考试成绩
mysql>deletefrom exam_result where name like"孙%";
Query OK,1row affected (0.01 sec)

mysql>-- 删除数学第一名的同学的考试成绩
mysql>-deletefrom exam_result orderby math desclimit1;

mysql>-- 删除整张exam_result表
mysql>deletefrom exam_result ;

注意

delete from 表名

drop 表名

前者是表里面的内容删除,但是表还在,而后者是表整个都直接删除了。

5.数据库约束

5.1 约束类型

  1. NOT NULL - 指示某列不能存储 NULL 值。
  2. UNIQUE - 保证某列的每行必须有唯一的值。
  3. DEFAULT - 规定没有给列赋值时的默认值。
  4. PRIMARY KEY - NOT NULL 和 UNIQUE 的结合。确保某列(或两个列多个列的结合)有唯一标 识,有助于更容易更快速地找到表中的一个特定的记录。
  5. FOREIGN KEY - 保证一个表中的数据匹配另一个表中的值的参照完整性。
  6. CHECK - 保证列中的值符合指定的条件。对于MySQL数据库,对CHECK子句进行分析,但是忽略 CHECK子句。

5.2 NULL 约束和 NOT NULL约束

创建表时,可以指定某列不为空:
示例

mysql>createtable student (id intnotnull,name varchar(20),qq_email varchar(10));
Query OK,0rows affected (0.03 sec)
mysql>desc student;+----------+-------------+------+-----+---------+-------+| Field    |Type|Null|Key|Default| Extra |+----------+-------------+------+-----+---------+-------+| id       |int(11)|NO||NULL||| name     |varchar(20)| YES  ||NULL||| qq_email |varchar(10)| YES  ||NULL||+----------+-------------+------+-----+---------+-------+3rowsinset(0.01 sec)

在设置了该列的约束NOT NULL后,此行一旦插入id = null 就会报错。

5.3 UNIQUE:唯一约束

插入数据或者修改数据的时候,就会先查询,先看看数据是否已经存在,如果不存在,就能够插入、修改成功,如果存在就插入或者修改失败。

示例:

mysql>createtable student (id intunique,name varchar(10)notnull);
Query OK,0rows affected (0.02 sec)

mysql>desc student;+-------+-------------+------+-----+---------+-------+| Field |Type|Null|Key|Default| Extra |+-------+-------------+------+-----+---------+-------+| id    |int(11)| YES  | UNI |NULL||| name  |varchar(10)|NO||NULL||+-------+-------------+------+-----+---------+-------+2rowsinset(0.00 sec)

mysql>insertinto student values(1,"zhangsan");
Query OK,1row affected (0.00 sec)

mysql>select*from student;+------+----------+| id   | name     |+------+----------+|1| zhangsan |+------+----------+1rowinset(0.00 sec)

mysql>insertinto student values(1,"lisi");
ERROR 1062(23000): Duplicate entry '1'forkey'id'

duplicate 重复的,entry 条目,入口

5.4 DEFAULT:默认值约束

  1. 默认值是insert指定列插入的时候其他未被指定到的列就是按照默认值来填充。
  2. 我们在建表的时候,如果不指定默认值,那么SQL也会自动设置默认值为null。

示例:
指定插入数据时,name列为空,默认值“无名氏”

mysql>droptableifexists student;
Query OK,0rows affected (0.01 sec)

mysql>createtable student(id intunique,name varchar(20)default"无名氏");
Query OK,0rows affected (0.02 sec)

mysql>insertinto student(id)values(1);
Query OK,1row affected (0.00 sec)

mysql>select*from student;+------+--------+| id   | name   |+------+--------+|1| 无名氏 |+------+--------+1rowinset(0.00 sec)

5.5 PRIMARY KEY:主键约束

  1. 主键是一条记录在表中的身份标识,唯一标记每一条数据
  2. mySQL要求主键所标识的列(属性)是唯一的(unique)、且不能为空(not null)
  3. 一个表里只能有一个主键
  4. 创建主键的时候,可以使用一个列作为主键,但是也可以用两个或者更多的列作为主键(复合主键)。但是一般项目中,一个表里就以一个列作为主键。
mysql>droptableifexists student;
Query OK,0rows affected (0.01 sec)

mysql>createtable student (id intprimarykey,name varchar(20)notnull);
Query OK,0rows affected (0.02 sec)

mysql>desc student;+-------+-------------+------+-----+---------+-------+| Field |Type|Null|Key|Default| Extra |+-------+-------------+------+-----+---------+-------+| id    |int(11)|NO| PRI |NULL||| name  |varchar(20)|NO||NULL||+-------+-------------+------+-----+---------+-------+2rowsinset(0.00 sec)
  1. 对于整数类型的主键,常配搭自增长auto_increment来使用。插入数据对应字段不给值时,使用最大值+1。也就是说mySQl自己会维护一个类似全局变量的自增主键,在我们设置该属性为整数类型的主键后,该属性插入是可以不赋值(即可以为null)此时,MySQL会根据当前主键的最大值加1来赋值为当前这一行记录的主键值。
  2. 自增主键一般只适用于数据是单机部署的,此时自增主键一般是够用的,但是如果自增主键是分布式部署,一般是不适用自增主键的。

示例

mysql>droptableifexists student;
Query OK,0rows affected (0.01 sec)
ysql>createtable student (id intprimarykeyauto_increment,name varchar(20));
Query OK,0rows affected (0.02 sec)

mysql>desc student;+-------+-------------+------+-----+---------+----------------+| Field |Type|Null|Key|Default| Extra          |+-------+-------------+------+-----+---------+----------------+| id    |int(11)|NO| PRI |NULL|auto_increment|| name  |varchar(20)| YES  ||NULL||+-------+-------------+------+-----+---------+----------------+2rowsinset(0.00 sec)

mysql>insertinto student(name)values("张三");
Query OK,1row affected (0.00 sec)

mysql>select*from student;+----+------+| id | name |+----+------+|1| 张三 |+----+------+1rowinset(0.00 sec)
mysql>insertinto student(id,name)values(null,"李四");
Query OK,1row affected (0.00 sec)

mysql>select*from student;+----+------+| id | name |+----+------+|1| 张三 ||2| 李四 |+----+------+2rowsinset(0.00 sec)

mysql>insertinto student values(100,"王五");
Query OK,1row affected (0.00 sec)

mysql>select*from student;+-----+------+| id  | name |+-----+------+|1| 张三 ||2| 李四 ||100| 王五 |+-----+------+3rowsinset(0.00 sec)

mysql>select*from student;+-----+------+| id  | name |+-----+------+|1| 张三 ||2| 李四 ||100| 王五 ||101| 六六 |+-----+------+4rowsinset(0.00 sec)

5.6 FOREIGN KEY:外键约束

语法:

foreignkey(字段名)references 主表(列)

示例

mysql>createtable class (classId intprimarykeyauto_increment,className varchar(20));
Query OK,0rows affected (0.02 sec)

mysql>droptableifexists student;
Query OK,0rows affected (0.01 sec)

mysql>createtable student(studentId intprimarykey,studentName varchar(20),classId int,->foreignkey(classId)references class(classId));
Query OK,0rows affected (0.02 sec)

mysql>desc student;+-------------+-------------+------+-----+---------+-------+| Field       |Type|Null|Key|Default| Extra |+-------------+-------------+------+-----+---------+-------+| studentId   |int(11)|NO| PRI |NULL||| studentName |varchar(20)| YES  ||NULL||| classId     |int(11)| YES  | MUL |NULL||+-------------+-------------+------+-----+---------+-------+3rowsinset(0.00 sec)

mysql>desc class;+-----------+-------------+------+-----+---------+----------------+| Field     |Type|Null|Key|Default| Extra          |+-----------+-------------+------+-----+---------+----------------+| classId   |int(11)|NO| PRI |NULL|auto_increment|| className |varchar(20)| YES  ||NULL||+-----------+-------------+------+-----+---------+----------------+2rowsinset(0.00 sec)
  1. 此时class表是空的,如果我在student表里面新增一个记录(这个记录中classId为1),那么这就会报错 示例:
mysql>insertinto student values(123,"zhangsan",1);
ERROR 1452(23000): Cannot addorupdate a child row: a foreignkeyconstraint fails (`base1`.`student`,CONSTRAINT`student_ibfk_1`FOREIGNKEY(`classId`)REFERENCES`class`(`classId`))

其中

Cannot add or update a child row: a foreign key constraint fails (

base1

.

student

, CONSTRAINT 

student_ibfk_1

 FOREIGN KEY (

classId

) REFERENCES 

class

 (

classId

))

student中的classId受到class表里面的classId约束,在MySQL中我们将student表称之为子表,class表称之为父表。这句话翻译过来“不能增加或者修改一个子行:一个外键约束(constraint)失败”

mysql>insertinto class values(null,"一班"),(null,"二班");
Query OK,2rows affected (0.00 sec)
Records: 2  Duplicates: 0Warnings: 0

mysql>select*from class;+---------+-----------+| classId | className |+---------+-----------+|1| 一班      ||2| 二班      |+---------+-----------+2rowsinset(0.00 sec)
mysql>insertinto student values(100,"张三",1),(101,"李四",2);
Query OK,2rows affected (0.00 sec)
Records: 2  Duplicates: 0Warnings: 0

mysql>select*from student;+-----------+-------------+---------+| studentId | studentName | classId |+-----------+-------------+---------+|100| 张三        |1||101| 李四        |2|+-----------+-------------+---------+2rowsinset(0.00 sec)

不但插入会影响,修改也是会影响,如果修改的classId的值并不在class表中,那么就会报错。

mysql>select*from student;+-----------+-------------+---------+| studentId | studentName | classId |+-----------+-------------+---------+|100| 张三        |1||101| 李四        |2|+-----------+-------------+-

mysql>update student set classId =2where studentId =100;
Query OK,1row affected (0.00 sec)Rowsmatched: 1  Changed: 1Warnings: 0

mysql>select*from student;+-----------+-------------+---------+| studentId | studentName | classId |+-----------+-------------+---------+|100| 张三        |2||101| 李四        |2|+-----------+-------------+---------+2rowsinset(0.00 sec)
  1. 同样如果我去删除class表中的数据依旧会报错,因为这里面的数据在student表中关联着,不能轻易删除。
mysql>select*from student;+-----------+-------------+---------+| studentId | studentName | classId |+-----------+-------------+---------+|1| zhangsan    |1||2| lisi        |2|+-----------+-------------+---------+2rowsinset(0.00 sec)

mysql>deletefrom  class where classId =1;
ERROR 1451(23000): Cannot deleteorupdate a parent row: a foreignkeyconstraint fails (`base1`.`student`,CONSTRAINT`student_ibfk_1`FOREIGNKEY(`classId`)REFERENCES`class`(`classId`))

那么此时如果我此时确实是有删除这个班级记录的需求的呢?
比如说现在班级改制,将二班这个记录删除,但是这student表不变,作为存根。那么这样我们就在class表里面在增加一个列,标记为删除,实际上是逻辑删除了。

6.SQL的进阶操作

示例:
先定义一些表用于测试数据。

mysql>createtable course(courseId intprimarykey,curseName varchar(20));
Query OK,0rows affected (0.02 sec)

mysql>createtable student(studentId intprimarykey,studentName varchar(20));
Query OK,0rows affected (0.01 sec)

mysql>createtable test(testId intprimarykeyauto_increment,studentId int,courseId int,foreignkey(studentId)references  student(studentId),foreignkey(courseId)references course(courseId));
Query OK,0rows affected (0.03 sec)
mysql>desc student;+-------------+-------------+------+-----+---------+-------+| Field       |Type|Null|Key|Default| Extra |+-------------+-------------+------+-----+---------+-------+| studentId   |int(11)|NO| PRI |NULL||| studentName |varchar(20)| YES  ||NULL||+-------------+-------------+------+-----+---------+-------+2rowsinset(0.00 sec)

mysql>desc course;+-----------+-------------+------+-----+---------+-------+| Field     |Type|Null|Key|Default| Extra |+-----------+-------------+------+-----+---------+-------+| courseId  |int(11)|NO| PRI |NULL||| curseName |varchar(20)| YES  ||NULL||+-----------+-------------+------+-----+---------+-------+2rowsinset(0.01 sec)

mysql>desc test;+-----------+---------+------+-----+---------+----------------+| Field     |Type|Null|Key|Default| Extra          |+-----------+---------+------+-----+---------+----------------+| testId    |int(11)|NO| PRI |NULL|auto_increment|| studentId |int(11)| YES  | MUL |NULL||| courseId  |int(11)| YES  | MUL |NULL||+-----------+---------+------+-----+---------+----------------+3rowsinset(0.01 sec)

6.1新增操作

插入查询结果

INSERTINTO table_name [(column[,column...])]SELECT...

示例
创建一张用户表,设计有userId用户ID、name姓名、studentId学号、sex性别。需要把已有的学生数据复制进来,可以复制的字段为name,studentId字段

mysql>createtableuser(userId intprimarykeyauto_increment,userName varchar(20),studentId int,sec varchar(10));
Query OK,0rows affected (0.02 sec)

mysql>descuser;+-----------+-------------+------+-----+---------+----------------+| Field     |Type|Null|Key|Default| Extra          |+-----------+-------------+------+-----+---------+----------------+| userId    |int(11)|NO| PRI |NULL|auto_increment|| userName  |varchar(20)| YES  ||NULL||| studentId |int(11)| YES  ||NULL||| sec       |varchar(10)| YES  ||NULL||+-----------+-------------+------+-----+---------+----------------+4rowsinset(0.00 sec)

mysql>insertinto student values(1,"a"),(2,"b"),(3,"c");
Query OK,3rows affected (0.00 sec)
Records: 3  Duplicates: 0Warnings: 0

mysql>insertintouser(userName,studentId)select studentName,studentId from student;
Query OK,3rows affected (0.00 sec)
Records: 3  Duplicates: 0Warnings: 0

mysql>select*from student;+-----------+-------------+| studentId | studentName |+-----------+-------------+|1| a           ||2| b           ||3| c           |+-----------+-------------+3rowsinset(0.00 sec)

mysql>select*fromuser;+--------+----------+-----------+------+| userId | userName | studentId | sec  |+--------+----------+-----------+------+|1| a        |1|NULL||2| b        |2|NULL||3| c        |3|NULL|+--------+----------+-----------+------+3rowsinset(0.00 sec)
  1. 这种方式列名可以不一致,但是数量和参数类型得一致

6.2聚合查询

常见的统计总数、计算平局值等操作,可以使用聚合函数来实现,常见的聚合函数有

在这里插入图片描述

6.2.1 count

示例:

mysql>select*from student;+-----------+-------------+| studentId | studentName |+-----------+-------------+|1| a           ||2| b           ||3| c           |+-----------+-------------+3rowsinset(0.00 sec)
mysql>selectcount(*)from student;+----------+|count(*)|+----------+|3|+----------+1rowinset(0.00 sec)

mysql>insertinto student values(4,"a");
Query OK,1row affected (0.00 sec)
  1. 使用DISTINCT 去重关键字,可以避免将相同记录计数。
mysql>insertinto student values(4,"a");
Query OK,1row affected (0.00 sec)

mysql>selectcount(name)from student;
ERROR 1054(42S22): Unknown column'name'in'field list'
mysql>selectcount(studentName)from student;+--------------------+|count(studentName)|+--------------------+|4|+--------------------+1rowinset(0.00 sec)

mysql>selectcount(distinct studentName)from student;+------------------------------+|count(distinct studentName)|+------------------------------+|3|+------------------------------+1rowinset(0.00 sec)
  1. 记录为null时是不参与count计数的。
mysql>insertinto student(studentId)values(5);
Query OK,1row affected (0.00 sec)

mysql>select*from student;+-----------+-------------+| studentId | studentName |+-----------+-------------+|1| a           ||2| b           ||3| c           ||4| a           ||5|NULL|+-----------+-------------+5rowsinset(0.00 sec)

mysql>selectcount(studentName)from student;+--------------------+|count(studentName)|+--------------------+|4|+--------------------+1rowinset(0.00 sec)

6.2.2 SUM

示例

mysql>DROPTABLEIFEXISTS exam_result;
Query OK,0rows affected (0.01 sec)

mysql>CREATETABLE exam_result (->     id INT,->     name VARCHAR(20),->     chinese DECIMAL(3,1),->     math DECIMAL(3,1),->     english DECIMAL(3,1)->);
Query OK,0rows affected (0.02 sec)

mysql>-- 插入测试数据
mysql>INSERTINTO exam_result (id,name, chinese, math, english)VALUES->(1,'唐三藏',67,98,56),->(2,'孙悟空',87.5,78,77),->(3,'猪悟能',88,98.5,90),->(4,'曹孟德',82,84,67),->(5,'刘玄德',55.5,85,45),->(6,'孙权',70,73,78.5),->(7,'宋公明',75,65,30);
Query OK,7rows affected (0.01 sec)
Records: 7  Duplicates: 0Warnings: 0

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|+------+--------+---------+------+---------+7rowsinset(0.00 sec)
  1. sum操作只作用于数据类型是数值类型的列。
mysql>selectsum(name)from exam_result;+-----------+|sum(name)|+-----------+|0|+-----------+1rowinset,8warnings(0.00 sec)

这里有8个warningsm,可以看一下warning

mysql>showwarnings;+---------+------+--------------------------------------------+|Level| Code | Message                                    |+---------+------+--------------------------------------------+| Warning |1292| Truncated incorrect DOUBLEvalue: '唐三藏'|| Warning |1292| Truncated incorrect DOUBLEvalue: '孙悟空'|| Warning |1292| Truncated incorrect DOUBLEvalue: '猪悟能'|| Warning |1292| Truncated incorrect DOUBLEvalue: '曹孟德'|| Warning |1292| Truncated incorrect DOUBLEvalue: '刘玄德'|| Warning |1292| Truncated incorrect DOUBLEvalue: '孙权'|| Warning |1292| Truncated incorrect DOUBLEvalue: '宋公明'|| Warning |1292| Truncated incorrect DOUBLEvalue: '贾宝玉'|+---------+------+--------------------------------------------+8rowsinset(0.00 sec)
  1. sum操作与+不同,可以自动跳过值为null进行累加,而不会返回null; 示例:
mysql>selectsum(chinese)from exam_result;+--------------+|sum(chinese)|+--------------+|525.0|+--------------+1rowinset(0.00 sec)

mysql>insertinto exam_result values(null,"贾宝玉",null,null,52.1);
Query OK,1row affected (0.00 sec)

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||NULL| 贾宝玉 |NULL|NULL|52.1|+------+--------+---------+------+---------+8rowsinset(0.00 sec)

mysql>selectsum(chinese)from exam_result;+--------------+|sum(chinese)|+--------------+|525.0|+--------------+1rowinset(0.00 sec)

6.2.3 聚合函数搭配where表达式查询

示例:
返回 > 70 分以上的数学最低分

mysql>selectmin(math)from exam_result where math>70;+-----------+|min(math)|+-----------+|73.0|+-----------+1rowinset(0.00 sec)

6.3 group by 子句

6.3.1分组

SELECT 中使用 GROUP BY 子句可以对指定列进行分组查询。需要满足:使用 GROUP BY 进行分组查询时,SELECT 指定的字段必须是“分组依据字段”,其他字段若想出现在SELECT 中则必须包含在聚合函数中。

语法

select column1,sum(column2),..fromtablegroupby column1,column3;

示例:
准备测试表及数据:职员表,有employerId(主键)、name(姓名)、role(角色)、salary(薪水)

mysql>createtable emp(->     id intprimarykeyauto_increment,->     name varchar(20)notnull,->     role varchar(20)notnull,->     salary numeric(11,2)->);
Query OK,0rows affected (0.02 sec)

mysql>insertinto emp(name, role, salary)values->('马云','服务员',1000.20),->('马化腾','游戏陪玩',2000.99),->('孙悟空','游戏角色',999.11),->('猪无能','游戏角色',333.5),->('沙和尚','游戏角色',700.33),->('隔壁老王','董事长',12000.66);
Query OK,6rows affected (0.00 sec)
Records: 6  Duplicates: 0Warnings: 0

mysql>select*from emp;+----+----------+----------+----------+| id | name     | role     | salary   |+----+----------+----------+----------+|1| 马云     | 服务员   |1000.20||2| 马化腾   | 游戏陪玩 |2000.99||3| 孙悟空   | 游戏角色 |999.11||4| 猪无能   | 游戏角色 |333.50||5| 沙和尚   | 游戏角色 |700.33||6| 隔壁老王 | 董事长   |12000.66|+----+----------+----------+----------+6rowsinset(0.00 sec)

查询每个角色的最高工资、最低工资和平均工资


mysql>select role,min(salary)as"最低工资",max(salary)as"最高工资",avg(salary)as"平均工资"from emp groupby role;+----------+----------+----------+--------------+| role     | 最低工资 | 最高工资 | 平均工资     |+----------+----------+----------+--------------+| 服务员   |1000.20|1000.20|1000.200000|| 游戏角色 |333.50|999.11|677.646667|| 游戏陪玩 |2000.99|2000.99|2000.990000|| 董事长   |12000.66|12000.66|12000.660000|+----------+----------+----------+--------------+4rowsinset(0.00 sec)

mysql>select name,min(salary)as"最低工资",max(salary)as"最高工资",avg(salary)as"平均工资"from emp groupby role;+----------+----------+----------+--------------+| name     | 最低工资 | 最高工资 | 平均工资     |+----------+----------+----------+--------------+| 马云     |1000.20|1000.20|1000.200000|| 孙悟空   |333.50|999.11|677.646667|| 马化腾   |2000.99|2000.99|2000.990000|| 隔壁老王 |12000.66|12000.66|12000.660000|+----------+----------+----------+--------------+4rowsinset(0.00 sec)

最后name作为select 查询是没哟意义的。只有role才有意义。

6.3.2 分组之前条件筛选

示例:

求去除孙悟空同学后的每个岗位的平均薪资。

mysql>select role,avg(salary)from emp where name !="孙悟空"groupby role;+----------+--------------+| role     |avg(salary)|+----------+--------------+| 服务员   |1000.200000|| 游戏角色 |516.915000|| 游戏陪玩 |2000.990000|| 董事长   |12000.660000|+----------+--------------+4rowsinset(0.00 sec)

where在group by 之前执行,先筛选出name中没有孙悟空的所有记录,再将这些记录分组,再去求这些记录的平均薪资。

6.3.3 分组之后条件筛选having条件

GROUP BY 子句进行分组以后,需要对分组结果再进行条件过滤时,不能使用 WHERE 语句,而需要用 HAVING
示例

mysql>select role,avg(salary)from emp groupby role having name !="孙悟空";
ERROR 1054(42S22): Unknown column'name'in'having clause'
mysql>select role,avg(salary)from emp groupby role having role !="董事长";+----------+-------------+| role     |avg(salary)|+----------+-------------+| 服务员   |1000.200000|| 游戏角色 |677.646667|| 游戏陪玩 |2000.990000|+----------+-------------+3rowsinset(0.00 sec)

注意:此时的having筛选对象一定是分组后的表里面有的列(属性),比如在上述中,name就不在分完组后的表中,所以会报错。

显示平均工资低于1500的角色和它的平均工资

mysql>select role,max(salary),min(salary),avg(salary)from emp groupby role
    ->havingavg(salary)<1500;+----------+-------------+-------------+-------------+| role     |max(salary)|min(salary)|avg(salary)|+----------+-------------+-------------+-------------+| 服务员   |1000.20|1000.20|1000.200000|| 游戏角色 |999.11|333.50|677.646667|+----------+-------------+-------------+-------------+2rowsinset(0.00 sec)

6.3.4 分组前查询与分组后查询结合

去除孙悟空同学后分组,求每个角色的平均薪资,并去除老板这一角色进行查询

mysql>select role,avg(salary)from emp where name !="孙悟空"groupby role having role !="董事长";+----------+-------------+| role     |avg(salary)|+----------+-------------+| 服务员   |1000.200000|| 游戏角色 |516.915000|| 游戏陪玩 |2000.990000|+----------+-------------+3rowsinset(0.00 sec)

实际上 where 和having 可以理解为一个执行在聚合函数之前,一个执行在聚合函数之后

mysql>select role,avg(salary)from emp where name !="孙悟空"having role !="董事长";+--------+-------------+| role   |avg(salary)|+--------+-------------+| 服务员 |3207.136000|+--------+-------------+1rowinset(0.00 sec)

mysql>select role,avg(salary)from emp where name !="孙悟空";+--------+-------------+| role   |avg(salary)|+--------+-------------+| 服务员 |3207.136000|+--------+-------------+1rowinset(0.00 sec)

mysql>select role,avg(salary)from emp where name !="孙悟空"having role !="服务员";
Empty set(0.00 sec)

mysql>select role from emp where name !="孙悟空"having role !="服务员";+----------+| role     |+----------+| 游戏陪玩 || 游戏角色 || 游戏角色 || 董事长   |+----------+4rowsinset(0.00 sec)

7.联合查询

实际开发中往往数据来自不同的表,所以需要多表联合查询。多表查询是对多张表的数据取笛卡尔积。

在这里插入图片描述

  1. 如上图实际上笛卡尔积得到的是一张更大的表,笛卡尔积的列数是两个表的列数之和,而行数是两个表的行数之积。
  2. 由于笛卡尔积是 排列组合出来的,所以有些数据是么有意义的。有意义的数据一定是两表里面的相同列(属性)的值一定是相同的。

示例:

建立三个表,班级表calsses、学生表student、课程表course

mysql>-- 创建班级表,有使用MySQL关键字作为字段时,需要使用``来标识
mysql>DROPTABLEIFEXISTS classes;
Query OK,0rows affected,1 warning (0.00 sec)

mysql>CREATETABLE classes (->     id INTPRIMARYKEYauto_increment,->     name VARCHAR(20),->`desc`VARCHAR(100)->);
Query OK,0rows affected (0.03 sec)

mysql>DROPTABLEIFEXISTS student;
Query OK,0rows affected,1 warning (0.00 sec)

mysql>CREATETABLE student (->     id INTPRIMARYKEYauto_increment,->     sn INTUNIQUE,->     name VARCHAR(20)DEFAULT'unkown',->     qq_mail VARCHAR(20),->     classes_id int,->FOREIGNKEY(classes_id)REFERENCES classes(id)->);
Query OK,0rows affected (0.02 sec)

mysql>-- 创建课程表
mysql>DROPTABLEIFEXISTS course;
Query OK,0rows affected,1 warning (0.00 sec)

mysql>CREATETABLE course (->     id INTPRIMARYKEYauto_increment,->     name VARCHAR(20)->);
Query OK,0rows affected (0.02 sec)

mysql>CREATETABLE score (->     id INTPRIMARYKEYauto_increment,->     score DECIMAL(3,1),->     student_id int,->     course_id int,->FOREIGNKEY(student_id)REFERENCES student(id),->FOREIGNKEY(course_id)REFERENCES course(id)->);
Query OK,0rows affected (0.02 sec)

mysql>desc classes;+-------+--------------+------+-----+---------+----------------+| Field |Type|Null|Key|Default| Extra          |+-------+--------------+------+-----+---------+----------------+| id    |int(11)|NO| PRI |NULL|auto_increment|| name  |varchar(20)| YES  ||NULL|||desc|varchar(100)| YES  ||NULL||+-------+--------------+------+-----+---------+----------------+3rowsinset(0.00 sec)

mysql>desc student;+------------+-------------+------+-----+---------+----------------+| Field      |Type|Null|Key|Default| Extra          |+------------+-------------+------+-----+---------+----------------+| id         |int(11)|NO| PRI |NULL|auto_increment|| sn         |int(11)| YES  | UNI |NULL||| name       |varchar(20)| YES  || unkown  ||| qq_mail    |varchar(20)| YES  ||NULL||| classes_id |int(11)| YES  | MUL |NULL||+------------+-------------+------+-----+---------+----------------+5rowsinset(0.00 sec)

mysql>desc course;+-------+-------------+------+-----+---------+----------------+| Field |Type|Null|Key|Default| Extra          |+-------+-------------+------+-----+---------+----------------+| id    |int(11)|NO| PRI |NULL|auto_increment|| name  |varchar(20)| YES  ||NULL||+-------+-------------+------+-----+---------+----------------+2rowsinset(0.00 sec)

mysql>desc score;+------------+--------------+------+-----+---------+----------------+| Field      |Type|Null|Key|Default| Extra          |+------------+--------------+------+-----+---------+----------------+| id         |int(11)|NO| PRI |NULL|auto_increment|| score      |decimal(3,1)| YES  ||NULL||| student_id |int(11)| YES  | MUL |NULL||| course_id  |int(11)| YES  | MUL |NULL||+------------+--------------+------+-----+---------+----------------+4rowsinset(0.00 sec)

插入数据为测试做准备

mysql>insertinto classes(name,`desc`)values->('计算机系2019级1班','学习了计算机原理、C和Java语言、数据结构和算法'),->('中文系2019级3班','学习了中国传统文学'),->('自动化2019级5班','学习了机械自动化');
Query OK,3rows affected (0.01 sec)
Records: 3  Duplicates: 0Warnings: 0

mysql>insertinto student(sn, name, qq_mail, classes_id)values->('09982','黑旋风李逵','[email protected]',1),->('00835','菩提老祖',null,1),->('00391','白素贞',null,1),->('00031','许仙','[email protected]',1),->('00054','不想毕业',null,1),->('51234','好好说话','[email protected]',2),->('83223','tellme',null,2),->('09527','老外学中文','[email protected]',2);
Query OK,8rows affected (0.01 sec)
Records: 8  Duplicates: 0Warnings: 0

mysql>insertinto course(name)values->('Java'),('中国传统文化'),('计算机原理'),('语文'),('高阶数学'),('英文');
Query OK,6rows affected (0.00 sec)
Records: 6  Duplicates: 0Warnings: 0

mysql>DROPTABLEIFEXISTS score;
Query OK,0rows affected,1 warning (0.00 sec)

mysql>CREATETABLE score (->     id INTPRIMARYKEYauto_increment,->     score DECIMAL(3,1),->     student_id int,->     course_id int,->FOREIGNKEY(student_id)REFERENCES student(id),->FOREIGNKEY(course_id)REFERENCES course(id)->);
Query OK,0rows affected (0.02 sec)

mysql>desc score;+------------+--------------+------+-----+---------+----------------+| Field      |Type|Null|Key|Default| Extra          |+------------+--------------+------+-----+---------+----------------+| id         |int(11)|NO| PRI |NULL|auto_increment|| score      |decimal(3,1)| YES  ||NULL||| student_id |int(11)| YES  | MUL |NULL||| course_id  |int(11)| YES  | MUL |NULL||+------------+--------------+------+-----+---------+----------------+4rowsinset(0.00 sec)

mysql>insertinto course(name)values->('Java'),('中国传统文化'),('计算机原理'),('语文'),('高阶数学'),('英文');
Query OK,6rows affected (0.00 sec)
Records: 6  Duplicates: 0Warnings: 0

mysql>insertinto score(score, student_id, course_id)values->-- 黑旋风李逵->(70.5,1,1),(98.5,1,3),(33,1,5),(98,1,6),->-- 菩提老祖->(60,2,1),(59.5,2,5),->-- 白素贞->(33,3,1),(68,3,3),(99,3,5),->-- 许仙->(67,4,1),(23,4,3),(56,4,5),(72,4,6),->-- 不想毕业->(81,5,1),(37,5,5),->-- 好好说话->(56,6,2),(43,6,4),(79,6,6),->-- tellme->(80,7,2),(92,7,6);
Query OK,20rows affected (0.01 sec)
Records: 20  Duplicates: 0Warnings: 0

mysql>select*from classes;+----+-------------------+-----------------------------------------------+| id | name              |desc|+----+-------------------+-----------------------------------------------+|1| 计算机系2019级1班 | 学习了计算机原理、C和Java语言、数据结构和算法 ||2| 中文系2019级3班   | 学习了中国传统文学                            ||3| 自动化2019级5班   | 学习了机械自动化                              |+----+-------------------+-----------------------------------------------+3rowsinset(0.00 sec)

mysql>select*from student;+----+-------+------------+------------------+------------+| id | sn    | name       | qq_mail          | classes_id |+----+-------+------------+------------------+------------+|1|9982| 黑旋风李逵 | [email protected]|1||2|835| 菩提老祖   |NULL|1||3|391| 白素贞     |NULL|1||4|31| 许仙       | [email protected]|1||5|54| 不想毕业   |NULL|1||6|51234| 好好说话   | [email protected]|2||7|83223| tellme     |NULL|2||8|9527| 老外学中文 | [email protected]|2|+----+-------+------------+------------------+------------+8rowsinset(0.00 sec)

mysql>select*from course;+----+--------------+| id | name         |+----+--------------+|1| Java         ||2| 中国传统文化 ||3| 计算机原理   ||4| 语文         ||5| 高阶数学     ||6| 英文         ||7| Java         ||8| 中国传统文化 ||9| 计算机原理   ||10| 语文         ||11| 高阶数学     ||12| 英文         |+----+--------------+12rowsinset(0.00 sec)

mysql>select*from score;+----+-------+------------+-----------+| id | score | student_id | course_id |+----+-------+------------+-----------+|1|70.5|1|1||2|98.5|1|3||3|33.0|1|5||4|98.0|1|6||5|60.0|2|1||6|59.5|2|5||7|33.0|3|1||8|68.0|3|3||9|99.0|3|5||10|67.0|4|1||11|23.0|4|3||12|56.0|4|5||13|72.0|4|6||14|81.0|5|1||15|37.0|5|5||16|56.0|6|2||17|43.0|6|4||18|79.0|6|6||19|80.0|7|2||20|92.0|7|6|+----+-------+------------+-----------+20rowsinset(0.00 sec)

7.1多表查询一般实现的步骤

  1. 分析清楚需求中,涉及到的信息在哪些表里;
  2. 针对对个表进行笛卡尔积
  3. 筛选出其中的有效信息(往往以两个表的外键作为关联条件)
  4. 结合需求中的条件,进一步筛选。

7.2 内连接

7.2.1通过from 表名1 ,表名2实现笛卡尔积

示例:
查询许仙同学的成绩
在查询之前先对score表和student表笛卡尔积

select * from score,student;
mysql>select*from student,score;+----+-------+------------+------------------+------------+----+-------+------------+-----------+| id | sn    | name       | qq_mail          | classes_id | id | score | student_id | course_id |+----+-------+------------+------------------+------------+----+-------+------------+-----------+|1|9982| 黑旋风李逵 | [email protected]|1|1|70.5|1|1||2|835| 菩提老祖   |NULL|1|1|70.5|1|1||3|391| 白素贞     |NULL|1|1|70.5|1|1||4|31| 许仙       | [email protected]|1|1|70.5|1|1||5|54| 不想毕业   |NULL|1|1|70.5|1|1||6|51234| 好好说话   | [email protected]|2|1|70.5|1|1||7|83223| tellme     |NULL|2|1|70.5|1|1||8|9527| 老外学中文 | [email protected]|2|1|70.5|1|1||1|9982| 黑旋风李逵 | [email protected]|1|2|98.5|1|3||2|835| 菩提老祖   |NULL|1|2|98.5|1|3||3|391| 白素贞     |NULL|1|2|98.5|1|3||4|31| 许仙       | [email protected]|1|2|98.5|1|3||5|54| 不想毕业   |NULL|1|2|98.5|1|3||6|51234| 好好说话   | [email protected]|2|2|98.5|1|3||7|83223| tellme     |NULL|2|2|98.5|1|3||8|9527| 老外学中文 | [email protected]|2|2|98.5|1|3||1|9982| 黑旋风李逵 | [email protected]|1|3|33.0|1|5||2|835| 菩提老祖   |NULL|1|3|33.0|1|5||3|391| 白素贞     |NULL|1|3|33.0|1|5||4|31| 许仙       | [email protected]|1|3|33.0|1|5||5|54| 不想毕业   |NULL|1|3|33.0|1|5||6|51234| 好好说话   | [email protected]|2|3|33.0|1|5||7|83223| tellme     |NULL|2|3|33.0|1|5||8|9527| 老外学中文 | [email protected]|2|3|33.0|1|5||1|9982| 黑旋风李逵 | [email protected]|1|4|98.0|1|6||2|835| 菩提老祖   |NULL|1|4|98.0|1|6||3|391| 白素贞     |NULL|1|4|98.0|1|6||4|31| 许仙       | [email protected]|1|4|98.0|1|6||5|54| 不想毕业   |NULL|1|4|98.0|1|6||6|51234| 好好说话   | [email protected]|2|4|98.0|1|6||7|83223| tellme     |NULL|2|4|98.0|1|6||8|9527| 老外学中文 | [email protected]|2|4|98.0|1|6||1|9982| 黑旋风李逵 | [email protected]|1|5|60.0|2|1||2|835| 菩提老祖   |NULL|1|5|60.0|2|1||3|391| 白素贞     |NULL|1|5|60.0|2|1||4|31| 许仙       | [email protected]|1|5|60.0|2|1||5|54| 不想毕业   |NULL|1|5|60.0|2|1||6|51234| 好好说话   | [email protected]|2|5|60.0|2|1||7|83223| tellme     |NULL|2|5|60.0|2|1||8|9527| 老外学中文 | [email protected]|2|5|60.0|2|1||1|9982| 黑旋风李逵 | [email protected]|1|6|59.5|2|5||2|835| 菩提老祖   |NULL|1|6|59.5|2|5||3|391| 白素贞     |NULL|1|6|59.5|2|5||4|31| 许仙       | [email protected]|1|6|59.5|2|5||5|54| 不想毕业   |NULL|1|6|59.5|2|5||6|51234| 好好说话   | [email protected]|2|6|59.5|2|5||7|83223| tellme     |NULL|2|6|59.5|2|5||8|9527| 老外学中文 | [email protected]|2|6|59.5|2|5||1|9982| 黑旋风李逵 | [email protected]|1|7|33.0|3|1||2|835| 菩提老祖   |NULL|1|7|33.0|3|1||3|391| 白素贞     |NULL|1|7|33.0|3|1||4|31| 许仙       | [email protected]|1|7|33.0|3|1||5|54| 不想毕业   |NULL|1|7|33.0|3|1||6|51234| 好好说话   | [email protected]|2|7|33.0|3|1||7|83223| tellme     |NULL|2|7|33.0|3|1||8|9527| 老外学中文 | [email protected]|2|7|33.0|3|1||1|9982| 黑旋风李逵 | [email protected]|1|8|68.0|3|3||2|835| 菩提老祖   |NULL|1|8|68.0|3|3||3|391| 白素贞     |NULL|1|8|68.0|3|3||4|31| 许仙       | [email protected]|1|8|68.0|3|3||5|54| 不想毕业   |NULL|1|8|68.0|3|3||6|51234| 好好说话   | [email protected]|2|8|68.0|3|3||7|83223| tellme     |NULL|2|8|68.0|3|3||8|9527| 老外学中文 | [email protected]|2|8|68.0|3|3||1|9982| 黑旋风李逵 | [email protected]|1|9|99.0|3|5||2|835| 菩提老祖   |NULL|1|9|99.0|3|5||3|391| 白素贞     |NULL|1|9|99.0|3|5||4|31| 许仙       | [email protected]|1|9|99.0|3|5||5|54| 不想毕业   |NULL|1|9|99.0|3|5||6|51234| 好好说话   | [email protected]|2|9|99.0|3|5||7|83223| tellme     |NULL|2|9|99.0|3|5||8|9527| 老外学中文 | [email protected]|2|9|99.0|3|5||1|9982| 黑旋风李逵 | [email protected]|1|10|67.0|4|1||2|835| 菩提老祖   |NULL|1|10|67.0|4|1||3|391| 白素贞     |NULL|1|10|67.0|4|1||4|31| 许仙       | [email protected]|1|10|67.0|4|1||5|54| 不想毕业   |NULL|1|10|67.0|4|1||6|51234| 好好说话   | [email protected]|2|10|67.0|4|1||7|83223| tellme     |NULL|2|10|67.0|4|1||8|9527| 老外学中文 | [email protected]|2|10|67.0|4|1||1|9982| 黑旋风李逵 | [email protected]|1|11|23.0|4|3||2|835| 菩提老祖   |NULL|1|11|23.0|4|3||3|391| 白素贞     |NULL|1|11|23.0|4|3||4|31| 许仙       | [email protected]|1|11|23.0|4|3||5|54| 不想毕业   |NULL|1|11|23.0|4|3||6|51234| 好好说话   | [email protected]|2|11|23.0|4|3||7|83223| tellme     |NULL|2|11|23.0|4|3||8|9527| 老外学中文 | [email protected]|2|11|23.0|4|3||1|9982| 黑旋风李逵 | [email protected]|1|12|56.0|4|5||2|835| 菩提老祖   |NULL|1|12|56.0|4|5||3|391| 白素贞     |NULL|1|12|56.0|4|5||4|31| 许仙       | [email protected]|1|12|56.0|4|5||5|54| 不想毕业   |NULL|1|12|56.0|4|5||6|51234| 好好说话   | [email protected]|2|12|56.0|4|5||7|83223| tellme     |NULL|2|12|56.0|4|5||8|9527| 老外学中文 | [email protected]|2|12|56.0|4|5||1|9982| 黑旋风李逵 | [email protected]|1|13|72.0|4|6||2|835| 菩提老祖   |NULL|1|13|72.0|4|6||3|391| 白素贞     |NULL|1|13|72.0|4|6||4|31| 许仙       | [email protected]|1|13|72.0|4|6||5|54| 不想毕业   |NULL|1|13|72.0|4|6||6|51234| 好好说话   | [email protected]|2|13|72.0|4|6||7|83223| tellme     |NULL|2|13|72.0|4|6||8|9527| 老外学中文 | [email protected]|2|13|72.0|4|6||1|9982| 黑旋风李逵 | [email protected]|1|14|81.0|5|1||2|835| 菩提老祖   |NULL|1|14|81.0|5|1||3|391| 白素贞     |NULL|1|14|81.0|5|1||4|31| 许仙       | [email protected]|1|14|81.0|5|1||5|54| 不想毕业   |NULL|1|14|81.0|5|1||6|51234| 好好说话   | [email protected]|2|14|81.0|5|1||7|83223| tellme     |NULL|2|14|81.0|5|1||8|9527| 老外学中文 | [email protected]|2|14|81.0|5|1||1|9982| 黑旋风李逵 | [email protected]|1|15|37.0|5|5||2|835| 菩提老祖   |NULL|1|15|37.0|5|5||3|391| 白素贞     |NULL|1|15|37.0|5|5||4|31| 许仙       | [email protected]|1|15|37.0|5|5||5|54| 不想毕业   |NULL|1|15|37.0|5|5||6|51234| 好好说话   | [email protected]|2|15|37.0|5|5||7|83223| tellme     |NULL|2|15|37.0|5|5||8|9527| 老外学中文 | [email protected]|2|15|37.0|5|5||1|9982| 黑旋风李逵 | [email protected]|1|16|56.0|6|2||2|835| 菩提老祖   |NULL|1|16|56.0|6|2||3|391| 白素贞     |NULL|1|16|56.0|6|2||4|31| 许仙       | [email protected]|1|16|56.0|6|2||5|54| 不想毕业   |NULL|1|16|56.0|6|2||6|51234| 好好说话   | [email protected]|2|16|56.0|6|2||7|83223| tellme     |NULL|2|16|56.0|6|2||8|9527| 老外学中文 | [email protected]|2|16|56.0|6|2||1|9982| 黑旋风李逵 | [email protected]|1|17|43.0|6|4||2|835| 菩提老祖   |NULL|1|17|43.0|6|4||3|391| 白素贞     |NULL|1|17|43.0|6|4||4|31| 许仙       | [email protected]|1|17|43.0|6|4||5|54| 不想毕业   |NULL|1|17|43.0|6|4||6|51234| 好好说话   | [email protected]|2|17|43.0|6|4||7|83223| tellme     |NULL|2|17|43.0|6|4||8|9527| 老外学中文 | [email protected]|2|17|43.0|6|4||1|9982| 黑旋风李逵 | [email protected]|1|18|79.0|6|6||2|835| 菩提老祖   |NULL|1|18|79.0|6|6||3|391| 白素贞     |NULL|1|18|79.0|6|6||4|31| 许仙       | [email protected]|1|18|79.0|6|6||5|54| 不想毕业   |NULL|1|18|79.0|6|6||6|51234| 好好说话   | [email protected]|2|18|79.0|6|6||7|83223| tellme     |NULL|2|18|79.0|6|6||8|9527| 老外学中文 | [email protected]|2|18|79.0|6|6||1|9982| 黑旋风李逵 | [email protected]|1|19|80.0|7|2||2|835| 菩提老祖   |NULL|1|19|80.0|7|2||3|391| 白素贞     |NULL|1|19|80.0|7|2||4|31| 许仙       | [email protected]|1|19|80.0|7|2||5|54| 不想毕业   |NULL|1|19|80.0|7|2||6|51234| 好好说话   | [email protected]|2|19|80.0|7|2||7|83223| tellme     |NULL|2|19|80.0|7|2||8|9527| 老外学中文 | [email protected]|2|19|80.0|7|2||1|9982| 黑旋风李逵 | [email protected]|1|20|92.0|7|6||2|835| 菩提老祖   |NULL|1|20|92.0|7|6||3|391| 白素贞     |NULL|1|20|92.0|7|6||4|31| 许仙       | [email protected]|1|20|92.0|7|6||5|54| 不想毕业   |NULL|1|20|92.0|7|6||6|51234| 好好说话   | [email protected]|2|20|92.0|7|6||7|83223| tellme     |NULL|2|20|92.0|7|6||8|9527| 老外学中文 | [email protected]|2|20|92.0|7|6|+----+-------+------------+------------------+------------+----+-------+------------+-----------+160rowsinset(0.00 sec)

但是这里面有很多的无效数据,我们需要将无效数据剔除,一般是添加两个表的外键相等。
通过“表名.列名”来访问每个表的某个列

mysql>select*from student,score where student.id = score.student_id;+----+-------+------------+-----------------+------------+----+-------+------------+-----------+| id | sn    | name       | qq_mail         | classes_id | id | score | student_id | course_id |+----+-------+------------+-----------------+------------+----+-------+------------+-----------+|1|9982| 黑旋风李逵 | [email protected]|1|1|70.5|1|1||1|9982| 黑旋风李逵 | [email protected]|1|2|98.5|1|3||1|9982| 黑旋风李逵 | [email protected]|1|3|33.0|1|5||1|9982| 黑旋风李逵 | [email protected]|1|4|98.0|1|6||2|835| 菩提老祖   |NULL|1|5|60.0|2|1||2|835| 菩提老祖   |NULL|1|6|59.5|2|5||3|391| 白素贞     |NULL|1|7|33.0|3|1||3|391| 白素贞     |NULL|1|8|68.0|3|3||3|391| 白素贞     |NULL|1|9|99.0|3|5||4|31| 许仙       | [email protected]|1|10|67.0|4|1||4|31| 许仙       | [email protected]|1|11|23.0|4|3||4|31| 许仙       | [email protected]|1|12|56.0|4|5||4|31| 许仙       | [email protected]|1|13|72.0|4|6||5|54| 不想毕业   |NULL|1|14|81.0|5|1||5|54| 不想毕业   |NULL|1|15|37.0|5|5||6|51234| 好好说话   | [email protected]|2|16|56.0|6|2||6|51234| 好好说话   | [email protected]|2|17|43.0|6|4||6|51234| 好好说话   | [email protected]|2|18|79.0|6|6||7|83223| tellme     |NULL|2|19|80.0|7|2||7|83223| tellme     |NULL|2|20|92.0|7|6|+----+-------+------------+-----------------+------------+----+-------+------------+-----------+20rowsinset(0.01 sec)

最后查询许仙同学的成绩

mysql>select student.name,score.score from student,score where student.id = score.student_id and student.name ="许仙";+------+-------+| name | score |+------+-------+| 许仙 |67.0|| 许仙 |23.0|| 许仙 |56.0|| 许仙 |72.0|+------+-------+4rowsinset(0.00 sec)

7.2.2通过join… on实现笛卡尔积

此外我们也可以通过join来实现笛卡尔积,此时后续条件也不是使用where关键字,而是 on

示例

mysql>select student.name,score.score from student join score on student.id = score.student_id and student.name ="许仙";+------+-------+| name | score |+------+-------+| 许仙 |67.0|| 许仙 |23.0|| 许仙 |56.0|| 许仙 |72.0|+------+-------+4rowsinset(0.00 sec)

查询所有同学的总成绩,及同学的个人信息。

mysql>select student.*,score.score from student,score where student.id = score.student_id;+----+-------+------------+-----------------+------------+-------+| id | sn    | name       | qq_mail         | classes_id | score |+----+-------+------------+-----------------+------------+-------+|1|9982| 黑旋风李逵 | [email protected]|1|70.5||1|9982| 黑旋风李逵 | [email protected]|1|98.5||1|9982| 黑旋风李逵 | [email protected]|1|33.0||1|9982| 黑旋风李逵 | [email protected]|1|98.0||2|835| 菩提老祖   |NULL|1|60.0||2|835| 菩提老祖   |NULL|1|59.5||3|391| 白素贞     |NULL|1|33.0||3|391| 白素贞     |NULL|1|68.0||3|391| 白素贞     |NULL|1|99.0||4|31| 许仙       | [email protected]|1|67.0||4|31| 许仙       | [email protected]|1|23.0||4|31| 许仙       | [email protected]|1|56.0||4|31| 许仙       | [email protected]|1|72.0||5|54| 不想毕业   |NULL|1|81.0||5|54| 不想毕业   |NULL|1|37.0||6|51234| 好好说话   | [email protected]|2|56.0||6|51234| 好好说话   | [email protected]|2|43.0||6|51234| 好好说话   | [email protected]|2|79.0||7|83223| tellme     |NULL|2|80.0||7|83223| tellme     |NULL|2|92.0|+----+-------+------------+-----------------+------------+-------+20rowsinset(0.00 sec)

注意上述查询的是每个同学对应课程的对应分数。而不是总分,那么要查询总分还需要进行分组结合聚合函数
去筛选出最后的总分数。

mysql>select student.id,student.name,sum(score.score)from student,score where student.id = score.student_id groupby student.id;+----+------------+------------------+| id | name       |sum(score.score)|+----+------------+------------------+|1| 黑旋风李逵 |300.0||2| 菩提老祖   |119.5||3| 白素贞     |200.0||4| 许仙       |218.0||5| 不想毕业   |118.0||6| 好好说话   |178.0||7| tellme     |172.0|+----+------------+------------------+7rowsinset(0.00 sec)

三个表也可以连接,显示学生所有课程的成绩

mysql>select*from student,course,score where student.id = score.student_id and course.id = score.course_id;+----+-------+------------+-----------------+------------+----+--------------+----+-------+------------+-----------+| id | sn    | name       | qq_mail         | classes_id | id | name         | id | score | student_id | course_id |+----+-------+------------+-----------------+------------+----+--------------+----+-------+------------+-----------+|1|9982| 黑旋风李逵 | [email protected]|1|1| Java         |1|70.5|1|1||1|9982| 黑旋风李逵 | [email protected]|1|3| 计算机原理   |2|98.5|1|3||1|9982| 黑旋风李逵 | [email protected]|1|5| 高阶数学     |3|33.0|1|5||1|9982| 黑旋风李逵 | [email protected]|1|6| 英文         |4|98.0|1|6||2|835| 菩提老祖   |NULL|1|1| Java         |5|60.0|2|1||2|835| 菩提老祖   |NULL|1|5| 高阶数学     |6|59.5|2|5||3|391| 白素贞     |NULL|1|1| Java         |7|33.0|3|1||3|391| 白素贞     |NULL|1|3| 计算机原理   |8|68.0|3|3||3|391| 白素贞     |NULL|1|5| 高阶数学     |9|99.0|3|5||4|31| 许仙       | [email protected]|1|1| Java         |10|67.0|4|1||4|31| 许仙       | [email protected]|1|3| 计算机原理   |11|23.0|4|3||4|31| 许仙       | [email protected]|1|5| 高阶数学     |12|56.0|4|5||4|31| 许仙       | [email protected]|1|6| 英文         |13|72.0|4|6||5|54| 不想毕业   |NULL|1|1| Java         |14|81.0|5|1||5|54| 不想毕业   |NULL|1|5| 高阶数学     |15|37.0|5|5||6|51234| 好好说话   | [email protected]|2|2| 中国传统文化 |16|56.0|6|2||6|51234| 好好说话   | [email protected]|2|4| 语文         |17|43.0|6|4||6|51234| 好好说话   | [email protected]|2|6| 英文         |18|79.0|6|6||7|83223| tellme     |NULL|2|2| 中国传统文化 |19|80.0|7|2||7|83223| tellme     |NULL|2|6| 英文         |20|92.0|7|6|+----+-------+------------+-----------------+------------+----+--------------+----+-------+------------+-----------+20rowsinset(0.01 sec)

mysql>select student.name,course.name,score.score from student,course,score where student.id = score.student_id and course.id = score.course_id;+------------+--------------+-------+| name       | name         | score |+------------+--------------+-------+| 黑旋风李逵 | Java         |70.5|| 黑旋风李逵 | 计算机原理   |98.5|| 黑旋风李逵 | 高阶数学     |33.0|| 黑旋风李逵 | 英文         |98.0|| 菩提老祖   | Java         |60.0|| 菩提老祖   | 高阶数学     |59.5|| 白素贞     | Java         |33.0|| 白素贞     | 计算机原理   |68.0|| 白素贞     | 高阶数学     |99.0|| 许仙       | Java         |67.0|| 许仙       | 计算机原理   |23.0|| 许仙       | 高阶数学     |56.0|| 许仙       | 英文         |72.0|| 不想毕业   | Java         |81.0|| 不想毕业   | 高阶数学     |37.0|| 好好说话   | 中国传统文化 |56.0|| 好好说话   | 语文         |43.0|| 好好说话   | 英文         |79.0|| tellme     | 中国传统文化 |80.0|| tellme     | 英文         |92.0|+------------+--------------+-------+20rowsinset(0.00 sec)

7.3 外连接

外连接分为左外连接和右外连接。如果联合查询,左侧的表完全显示我们就说是左外连接;右侧的表完
全显示我们就说是右外连接。
内连接与外连接大体是相同的,但是如果两个表的数据并不是一一对应的,此时进行内连接。结果只会显示两个表里面都有体现的数据。
如果进行左外连接。就是以左侧表为准,左侧表的数据都能体现出来。如果是右链接,就是以右侧表为准,右侧表数据都能体现出来。

-- 左外连接,表1完全显示select 字段名  from 表名1leftjoin 表名2on 连接条件;-- 右外连接,表2完全显示select 字段 from 表名1rightjoin 表名2on 连接条件;

示例:

mysql>-- "老外学中文"同学    没有考试成绩(course—id和studentid都是空的),也显示出来了
mysql>select*from student stu leftjoin score sco on stu.id=sco.student_id;+----+-------+------------+------------------+------------+------+-------+------------+-----------+| id | sn    | name       | qq_mail          | classes_id | id   | score | student_id | course_id |+----+-------+------------+------------------+------------+------+-------+------------+-----------+|1|9982| 黑旋风李逵 | [email protected]|1|1|70.5|1|1||1|9982| 黑旋风李逵 | [email protected]|1|2|98.5|1|3||1|9982| 黑旋风李逵 | [email protected]|1|3|33.0|1|5||1|9982| 黑旋风李逵 | [email protected]|1|4|98.0|1|6||2|835| 菩提老祖   |NULL|1|5|60.0|2|1||2|835| 菩提老祖   |NULL|1|6|59.5|2|5||3|391| 白素贞     |NULL|1|7|33.0|3|1||3|391| 白素贞     |NULL|1|8|68.0|3|3||3|391| 白素贞     |NULL|1|9|99.0|3|5||4|31| 许仙       | [email protected]|1|10|67.0|4|1||4|31| 许仙       | [email protected]|1|11|23.0|4|3||4|31| 许仙       | [email protected]|1|12|56.0|4|5||4|31| 许仙       | [email protected]|1|13|72.0|4|6||5|54| 不想毕业   |NULL|1|14|81.0|5|1||5|54| 不想毕业   |NULL|1|15|37.0|5|5||6|51234| 好好说话   | [email protected]|2|16|56.0|6|2||6|51234| 好好说话   | [email protected]|2|17|43.0|6|4||6|51234| 好好说话   | [email protected]|2|18|79.0|6|6||7|83223| tellme     |NULL|2|19|80.0|7|2||7|83223| tellme     |NULL|2|20|92.0|7|6||8|9527| 老外学中文 | [email protected]|2|NULL|NULL|NULL|NULL|+----+-------+------------+------------------+------------+------+-------+------------+-----------+21rowsinset(0.00 sec)

mysql>-- 对应的右外连接为:
mysql>select*from  score sco rightjoin student stu on stu.id=sco.student_id;+------+-------+------------+-----------+----+-------+------------+------------------+------------+| id   | score | student_id | course_id | id | sn    | name       | qq_mail          | classes_id |+------+-------+------------+-----------+----+-------+------------+------------------+------------+|1|70.5|1|1|1|9982| 黑旋风李逵 | [email protected]|1||2|98.5|1|3|1|9982| 黑旋风李逵 | [email protected]|1||3|33.0|1|5|1|9982| 黑旋风李逵 | [email protected]|1||4|98.0|1|6|1|9982| 黑旋风李逵 | [email protected]|1||5|60.0|2|1|2|835| 菩提老祖   |NULL|1||6|59.5|2|5|2|835| 菩提老祖   |NULL|1||7|33.0|3|1|3|391| 白素贞     |NULL|1||8|68.0|3|3|3|391| 白素贞     |NULL|1||9|99.0|3|5|3|391| 白素贞     |NULL|1||10|67.0|4|1|4|31| 许仙       | [email protected]|1||11|23.0|4|3|4|31| 许仙       | [email protected]|1||12|56.0|4|5|4|31| 许仙       | [email protected]|1||13|72.0|4|6|4|31| 许仙       | [email protected]|1||14|81.0|5|1|5|54| 不想毕业   |NULL|1||15|37.0|5|5|5|54| 不想毕业   |NULL|1||16|56.0|6|2|6|51234| 好好说话   | [email protected]|2||17|43.0|6|4|6|51234| 好好说话   | [email protected]|2||18|79.0|6|6|6|51234| 好好说话   | [email protected]|2||19|80.0|7|2|7|83223| tellme     |NULL|2||20|92.0|7|6|7|83223| tellme     |NULL|2||NULL|NULL|NULL|NULL|8|9527| 老外学中文 | [email protected]|2|+------+-------+------------+-----------+----+-------+------------+------------------+------------+21rowsinset(0.00 sec)

7.4多表(三张以上)联合查询

语法:

select 列名1,列名2....from 表名1,表名2,表名3where 条件1and 条件2;
select 列名1,列名2....from 表名1join 表名2on 条件1join 表名3on 条件2

示例:

mysql>-- 学生表、成绩表、课程表3张表关联查询
mysql>SELECT->     stu.id,->     stu.sn,->     stu.NAME,->     stu.qq_mail,->     sco.score,->     sco.course_id,->     cou.NAME
    ->FROM->     student stu
    ->LEFTJOIN score sco ON stu.id = sco.student_id
    ->LEFTJOIN course cou ON sco.course_id = cou.id
    ->ORDERBY->     stu.id;+----+-------+------------+------------------+-------+-----------+--------------+| id | sn    | NAME       | qq_mail          | score | course_id | NAME         |+----+-------+------------+------------------+-------+-----------+--------------+|1|9982| 黑旋风李逵 | [email protected]|70.5|1| Java         ||1|9982| 黑旋风李逵 | [email protected]|98.5|3| 计算机原理   ||1|9982| 黑旋风李逵 | [email protected]|33.0|5| 高阶数学     ||1|9982| 黑旋风李逵 | [email protected]|98.0|6| 英文         ||2|835| 菩提老祖   |NULL|60.0|1| Java         ||2|835| 菩提老祖   |NULL|59.5|5| 高阶数学     ||3|391| 白素贞     |NULL|33.0|1| Java         ||3|391| 白素贞     |NULL|68.0|3| 计算机原理   ||3|391| 白素贞     |NULL|99.0|5| 高阶数学     ||4|31| 许仙       | [email protected]|67.0|1| Java         ||4|31| 许仙       | [email protected]|23.0|3| 计算机原理   ||4|31| 许仙       | [email protected]|56.0|5| 高阶数学     ||4|31| 许仙       | [email protected]|72.0|6| 英文         ||5|54| 不想毕业   |NULL|81.0|1| Java         ||5|54| 不想毕业   |NULL|37.0|5| 高阶数学     ||6|51234| 好好说话   | [email protected]|56.0|2| 中国传统文化 ||6|51234| 好好说话   | [email protected]|43.0|4| 语文         ||6|51234| 好好说话   | [email protected]|79.0|6| 英文         ||7|83223| tellme     |NULL|80.0|2| 中国传统文化 ||7|83223| tellme     |NULL|92.0|6| 英文         ||8|9527| 老外学中文 | [email protected]|NULL|NULL|NULL|+----+-------+------------+------------------+-------+-----------+--------------+21rowsinset(0.00 sec)

7.5 自连接

自连接是在特殊情况下的特殊操作,不是一般用法。
SQL 中进行条件查询,都是指定某一列或者多个列之间进行关系运算,无法进行行与行之间的关系运算。有时候为了实现这种行之前的比较,就需要将行关系转换为列关系。

示例:

mysql>select*from score;+----+-------+------------+-----------+| id | score | student_id | course_id |+----+-------+------------+-----------+|1|70.5|1|1||2|98.5|1|3||3|33.0|1|5||4|98.0|1|6||5|60.0|2|1||6|59.5|2|5||7|33.0|3|1||8|68.0|3|3||9|99.0|3|5||10|67.0|4|1||11|23.0|4|3||12|56.0|4|5||13|72.0|4|6||14|81.0|5|1||15|37.0|5|5||16|56.0|6|2||17|43.0|6|4||18|79.0|6|6||19|80.0|7|2||20|92.0|7|6|+----+-------+------------+-----------+20rowsinset(0.00 sec)

比如说我要查询course_id为1的课程比course_id为3的课程分数高的学生的学生id。

mysql>select*from score as s1, score as s2 where s1.student_id = s2.student_id and s1.course_id =1and s2.course_id =3;+----+-------+------------+-----------+----+-------+------------+-----------+| id | score | student_id | course_id | id | score | student_id | course_id |+----+-------+------------+-----------+----+-------+------------+-----------+|1|70.5|1|1|2|98.5|1|3||7|33.0|3|1|8|68.0|3|3||10|67.0|4|1|11|23.0|4|3|+----+-------+------------+-----------+----+-------+------------+-----------+3rowsinset(0.00 sec)

注意:自连接一定要将表重新命名,保证连接的两个表的名字是不同的

mysql>select*from score as s1, score as s2 where s1.student_id = s2.student_id and s1.course_id =1and s2.course_id =3and s1.score> s2.score;+----+-------+------------+-----------+----+-------+------------+-----------+| id | score | student_id | course_id | id | score | student_id | course_id |+----+-------+------------+-----------+----+-------+------------+-----------+|10|67.0|4|1|11|23.0|4|3|+----+-------+------------+-----------+----+-------+------------+-----------+1rowinset(0.00 sec)

7.6子查询

子查询在实际开发过程中也要慎重。因为嵌套层次多了,对于代码可读性而言会变差。

7.6.1单行子查询

示例:

查询与“不想毕业”同学同班的同学

mysql>select*from student where student.classes_id =(select classes_id from student where student.name ="不想毕业");+----+------+------------+-----------------+------------+| id | sn   | name       | qq_mail         | classes_id |+----+------+------------+-----------------+------------+|1|9982| 黑旋风李逵 | [email protected]|1||2|835| 菩提老祖   |NULL|1||3|391| 白素贞     |NULL|1||4|31| 许仙       | [email protected]|1||5|54| 不想毕业   |NULL|1|+----+------+------------+-----------------+------------+5rowsinset(0.00 sec)

7.6.2多行子查询

查询“语文”或“英文”课程的成绩信息

mysql>select id from course where name ="英文"or name ="语文";+----+| id |+----+|4||6||10||12|+----+4rowsinset(0.00 sec)
mysql>select*from score where score.id in(4,6,10,12);+----+-------+------------+-----------+| id | score | student_id | course_id |+----+-------+------------+-----------+|4|98.0|1|6||6|59.5|2|5||10|67.0|4|1||12|56.0|4|5|+----+-------+------------+-----------+4rowsinset(0.00 sec)

用一行代码来完成就是

mysql>select*from score where course_id in(select id from course where name ="英文"or name ="语文");+----+-------+------------+-----------+| id | score | student_id | course_id |+----+-------+------------+-----------+|17|43.0|6|4||4|98.0|1|6||13|72.0|4|6||18|79.0|6|6||20|92.0|7|6|+----+-------+------------+-----------+5rowsinset(0.00 sec)

7.7 合并查询

在实际应用中,为了合并多个select的执行结果,可以使用集合操作符 union,union all。
语法:

select 列名1、列名2.....from 表名1where条件1unionselect 列名3、列名4.....from 表名2where 条件2;
select 列名1、列名2.....from 表名1where条件1unionallselect 列名3、列名4.....from 表名2where 条件2;
  1. union的实际步骤是先执行前一句select 得出一个查询结果的临时表,然后执行后一句select得到一个查询结果的临时表,两个表进行上下拼接。union在此过程中去重,union在此过程不去重。
  2. 使用UNION 和UNION ALL时,前后查询的结果集中,字段(列)数量需要一致。
  3. 该操作符用于取得两个结果集的并集。(和or的使用时类似的,但or是对列操作,union是对行操作)当使用该操作符时,会自动去掉结果集中的重复行。
  4. UNION查询时会去重,UNION ALL查询的时候不会去重。
mysql>select*from course where id<3or name ="英文";+----+--------------+| id | name         |+----+--------------+|1| Java         ||2| 中国传统文化 ||6| 英文         ||12| 英文         |+----+--------------+4rowsinset(0.01 sec)

mysql>select*from course where id<3unionselect*from course where name ='英文';+----+--------------+| id | name         |+----+--------------+|1| Java         ||2| 中国传统文化 ||6| 英文         ||12| 英文         |+----+--------------+4rowsinset(0.01 sec)

SQL的基本操作的详解就到这里了。如果真的有一字不漏看到这里的小伙伴,相信你是有收获的。

标签: mysql 数据库 详解

本文转载自: https://blog.csdn.net/baixian110/article/details/130970983
版权归原作者 baixian110 所有, 如有侵权,请联系我们删除。

“MySQL所有基本操作详解”的评论:

还没有评论