[toc]

MySQL对比Linux处理文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 显示后几行
tail
select * from world.city order by id desc limit 10;

# 显示前几行
head
select * from world.city limit 10;

# 排序
sort
order by

# 过滤列
awk
select name,population from world.city limit 10;

# 过滤字符
grep
like '%xxx%'

MySQL客户端命令及SQL语句

MySQL客户端命令

  • mysql

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    # 登陆命令
    -u:指定用户
    -p:指定密码
    -S:指定socket
    -h:指定主机域
    -e:免交互执行SQL语句
    -P:指定端口

    # 连接到数据库后(命令)
    status || \s # 查看数据库基本状态
    help || \h || ? # 查看客户端命令的帮助
    clear || \c # 终止当前的命令
    ego || \G # 格式化输出结果
    quit || exit || \q # 退出MySQL命令行
    source || \. # 导入数据
    system || \! # 执行系统命令
    tee || \T # 记录日志
    Ctrl +c || \c # MySQL5.6中会退出数据库,MySQL5.7中会终止当前的SQL

    # 修改MySQL命令提示符
    prompt=MySQL5.7[\d]>
  • mysqladmin

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    # 语法结构
    mysqladmin -u账号 -p密码 命令 参数

    # 命令
    ping # 检测MySQL是否存活
    shutdown # 停止数据库服务
    create # 创建数据库
    drop # 删除数据库
    password # 设置或更改密码
    flush-log # 库外执行刷新日志(binlog)
    variables # 查看MySQL的默认配置参数
    reload # 重新加载缓存

    # 检测MySQL是否存活
    mysqladmin -uroot -p789 ping

    # 停止数据库服务
    mysqladmin -uroot -p789 shutdown

    # 免交互建库
    mysqladmin -uroot -p789 create zls

    # 免交互删库
    mysqladmin -uroot -p789 drop zls

    # 设置或更改密码
    mysqladmin -uroot -p789 password '123'

    # 库外执行刷新日志(binlog)
    mysqladmin -uroot -p123 flush-log

    # 查看MySQL的默认配置参数
    mysqladmin -uroot -p123 variables

    # 重新加载缓存
    mysqladmin -uroot -p123 reload
  • mysqldump(做备份、导出数据)

DDL:数据定义语言(元数据)

‘库’和’表’的定义:对库表的增删改

1
2
3
4
5
6
7
8
9
10
11
12
13
# 增
create database # 创建库
create table # 创建表

# 删
drop database # 删库
drop table # 删表

# 改
alter database # 改库
alter table # 改表

# 查(DQL)

‘库’定义语言

语法属性

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 建库语法结构
Name: 'CREATE DATABASE'
Syntax:
CREATE {DATABASE | SCHEMA} [IF NOT EXISTS] db_name
[create_option] ...
create_option: [DEFAULT] {
CHARACTER SET [=] charset_name
| COLLATE [=] collation_name
}

# 语法
database or schema # 创建数据库
if not exists # 数据库不存在则创建,如果存在则不报错
character set = utf8 # 创建数据库时,指定字符集
charset utf8 # 创建数据库时,指定字符集
collate utf8_bin # 创建数据库时,指定校验规则
character_set_server=utf8 # 修改配置文件指定字符集
drop database # 删除数据库
alter database # 修改库属性

编辑库结构

  • 1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    # 语法格式
    ## 方案一
    create database 库名;

    ## 方案二
    create schema 库名;

    # 示例
    ## 数据库不存在则创建,如果存在则不报错
    create schema if not exists 库名;

    ## 创建数据库时,指定字符集
    create database if not exists 库名 character set = utf8;
    create database if not exists 库名 charset utf8;

    ## 创建数据库时,指定校验规则
    create database if not exists 库名 charset utf8 collate utf8_bin;

    ## 修改配置文件指定字符集
    vim /etc/my.cnf
    [mysqld]
    character_set_server=utf8
  • 1
    2
    3
    # 语法格式
    ## 删除指定数据库
    drop database 库名;
  • 1
    2
    3
    # 语法格式
    ## 修改数据库的字符集、校验规则
    alter database 库名 charset utf8 collate utf8_bin;

数据类型

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 数字类型
int # 整型 -2^31 ~ (2^31)-1 即 -2147483648 ~ 2147483647
tinyint # 最小整型 -128 ~ 127 年龄

# 字符串类型
varchar(5) # 可变长的字符串
char(5) # 定长字符串

# 枚举类型
enum('A','B') # 选择

# 时间类型
timestamp # 1970-01-01 00:00:00 ~ 2038-01-19 03:14:07
datetime # 1000-01-01 00:00:00 ~ 9999-12-31 23:59:59

# 浮点型
float # 单精度浮点型
dubble # 双精度浮点型

‘表’定义语言

语法属性

1
2
3
4
5
6
7
8
9
10
11
12
13
# 建表语法格式
create table 库名.表名(字段名1 数据类型 字段属性,字段名2 数据类型 字段属性,主键('字段名1','字段名2'))字符集;

# 建表字段属性
null # 可以为空
not null # 非空
primary key # 主键索引 唯一 且 非空 (一张表中,只能设置一个主键)
unique key # 唯一键索引 唯一 可以为空 + not null
auto_increment # 自增
unsigned # 一般配合整型使用,非负数(无符号)
default # 设置默认值
zerofill # 使用0自动补全
comment # 备注

编辑表结构

  • 1
    2
    # 创建表
    create table 库名.表名(字段名1 数据类型 字段属性,字段名2 数据类型 字段属性,主键('字段名1','字段名2'))字符集;
  • 1
    2
    # 删除指定表
    drop table 库名.表名;
  • 1
    2
    # 改表名
    alter table 表名 rename 新表名;

建表示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
# 示例需求
student # 表名
id name age gender phone doa # 字段名

# 创建学生表
## 方案一:
mysql> use 库名;
mysql> create table 表名(字段名1 数据类型,字段名2 数据类型,字段名3 数据类型);
## 方案二:
mysql> create table 库名.表名(字段名1 数据类型,字段名2 数据类型,字段名3 数据类型);

# 创建表字段名
create table student(id int,name varchar(10),age tinyint,gender enum('f','m'),phone char(11),doa datetime)charset utf8;

# 插入表字段
mysql> insert into student(id,name,age,gender,phone,doa) value(1,'zhang3',20,'m','11223344556',NOW());

# 查看表
mysql> select * from student;
+------+--------+------+--------+-------------+----------+
| id | name | age | gender | phone | doa |
+------+--------+------+--------+-------------+----------+
| 1 | zhang3 | 20 | m | 11223344556 | 2023-04-04 10:34:27|
| 1 | wzk | -3 | f | 11223344538 | 2023-04-04 10:35:27|
| 1 | wzk | -3 | f | 11223344538 | 2023-04-04 10:36:01|
+------+--------+------+--------+-------------+----------+

---------------------最重要---------------------
# 优化后的建表语句
create table student(id int,name varchar(10),age tinyint,gender enum('f','m'),phone char(11),doa datetime)charset utf8;

# 添加规则后的建表语句
create table student(
id int(3) zerofill primary key auto_increment comment '学生学号',
name varchar(10) not null comment '学生姓名',
age tinyint unsigned not null comment '学生年龄',
gender enum('f','m') not null default 'm' comment '学生性别',
phone char(11) not null unique key comment '联系方式',
doa datetime not null default NOW() comment '入学时间'
) charset utf8;

# 主键优化后的建表语句
create table student(
id int(3) zerofill auto_increment comment '学生学号',
name varchar(10) not null comment '学生姓名',
age tinyint unsigned not null comment '学生年龄',
gender enum('f','m') not null default 'm' comment '学生性别',
phone char(11) comment '联系方式',
doa datetime not null default NOW() comment '入学时间',
primary key(id,phone)
) charset utf8;

编辑表字段

  • 1
    2
    3
    4
    5
    6
    7
    8
    # 增加字段名
    alter table 表名 add 字段名 char(3) not null;

    # 在指定字段后增加字段
    alter table 表名 add 字段名 varchar(5) not null after 字段名(在此之后);

    # 将字段放在最前面
    alter table 表名 add 字段名 varchar(5) not null first;
  • 1
    2
    # 删除指定字段
    alter table 表名 drop 字段名;
  • 1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    # 选项
    change # 可以修改字段名、数据类型、属性
    modify # 只能修改数据类型和属性

    # 修改字段数据类型
    alter table 表名 change 字段名 字段名 varchar(10);
    alter table 表名 modify 字段名 char(10);

    # 修改字段属性
    alter table 表名 modify 字段名 char(10) not null;
    alter table 表名 change 字段名 字段名 char(10) null default '1';

    # 修改字段名字
    alter table 表名 change 字段名 syh varchar(1);

image-20230703201257211

DML:数据操作语言(真实数据)

编辑表数据

语法属性

  • 增:insert

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    # 插入数据之前,需要知道表的表结构(了解有哪些字段)
    desc student3;

    # 语法格式
    ## 方案一
    insert into 库.表(字段1,字段2,字段3,字段4...) values('值1','值2',值3,'值4'...);

    ## 方案二
    insert 库.表(字段1,字段2,字段3,字段4...) values('值1','值2',值3,'值4'...);

    ## 方案三
    insert 库.表 values('值1','值2','值3','值4'...);

    ## 方案四
    insert 库.表(字段2,字段3,字段4...) values('值2',值3,'值4'...);

    ## 方案五:插入多条数据
    insert 库.表(字段2,字段3,字段4...)
    values('值2',值3,'值4'...),
    ('值2',值3,'值4'...);

    # 示例
    ## 示例一
    insert into student3(id,age,gender,name,phone,doa) values(2,80,'f','abc','12345678901',NOW());

    ## 示例二
    insert student3(id,age,gender,name,phone,doa) values(3,80,'f','abd','12345678902',NOW());

    ## 示例三
    insert student3 values(4,'abe',80,'f','12345678903',NOW());

    ## 示例四
    insert student3(age,gender,name,phone) values(30,'f','abf','12345678905');

    ## 示例五:插入多条数据
    insert student3(age,gender,name,phone)
    values(32,'m','abx','12345678908'),
    (31,'f','abz','12345678909');
  • 删:delete

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    # 语法格式
    ## 方案一
    delete from 表名;
    ## 方案二
    delete from 表名 where 条件;
    ## 方案三
    delete from 表名;

    # 示例
    ## 示例一:规范删除
    delete from student3 where id=4;

    ## 示例二:计算删除
    delete from student3 where id=14-3;

    ## 示例三:多条件删除
    delete from student3 where name='abz' and doa='2023-04-05 09:00:01';

    ## 示例四:多条件删除
    delete from student3 where name='abz' or name='abx';

    ## 示例五:多条件删除
    delete from student3 where id>=9 and id<14;

    ## 示例六:多条件删除
    delete from student3 where id=14 or id=21 or id=18;

    ## 示例七:多条件删除
    delete from student3 where name in ('abz','abe');
  • 改:update

    1
    2
    3
    4
    5
    6
    7
    # 语法格式
    update 库.表 set 被修改的字段='被修改的值' where 条件;

    ## 注意:只有在修改mysql.user表中的用户信息时,才需要执行 flush

    # 示例
    update student3 set name='zls' where id=17;

如何使用update代替delete做伪删除

1
2
3
4
5
6
7
8
# 给表中添加状态列(添加一个字段)
alter table student3 add status enum('0','1') not null default '1' comment '物品状态';

# 使用update删除数据(变更状态信息)
update student3 set status='0' where id=31;

# 查询数据时,接状态条件进行查询
select * from student3 where status='1';

DCL:数据控制语言

编辑用户权限

语法属性

  • 授权:grant

    1
    2
    3
    4
    5
    # 语法格式
    ## 标准授权
    grant 权限 on 库.表 to 用户名@'主机域' identified by '密码';
    ## 授予所有特权='root'
    grant 权限 on 库.表 to 用户名@'主机域' identified by '密码' with grant option;
  • 安全限制

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    # 语法格式
    ## 单条限制
    grant 权限 on 库.表 to 用户名@'主机域' identified by '密码' with 安全限制 限制值;
    ## 单条限制多条限制
    grant 权限 on 库.表 to 用户名@'主机域' identified by '密码' with 安全限制 限制值 安全限制 限制值 安全限制 限制值;

    # 限制列表
    max_queries_per_hour # 用户每小时可查询次数(登陆mysql消耗一次查询)
    max_updates_per_hour # 用户每小时可更新次数(登陆mysql消耗一次查询)
    max_connections_per_hour # 用户每小时可连接服务器次数
    max_user_connections # 允许同时连接数量

    # 示例
    ## 用户每小时可查询次数(登陆mysql消耗一次)
    grant all on *.* to test_grant2@'%' identified by '123@qqdianCOM' with max_queries_per_hour 2;

    ## max_updates_per_hour:一个用户每小时可发出的更新数量
    grant all on *.* to test_grant4@'%' identified by '123@qqdianCOM' with max_queries_per_hour 3 max_updates_per_hour 1;

    ## max_connections_per_hour:一个用户每小时可连接到服务器的次数
    grant all on *.* to test_grant5@'%' identified by '123@qqdianCOM' with max_queries_per_hour 3 max_updates_per_hour 1 max_connections_per_hour 1;

    ## max_user_connections:允许同时连接数量
    grant all on *.* to test_grant6@'%' identified by '123@qqdianCOM' with max_user_connections 2;
  • 回收权限:revoke

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    # 语法格式
    revoke 权限 on 库.表 from 用户名@'主机域';

    # 权限列表
    SELECT,INSERT, UPDATE, DELETE, CREATE, DROP, RELOAD, SHUTDOWN, PROCESS, FILE, REFERENCES, INDEX, ALTER, SHOW DATABASES, SUPER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, REPLICATION SLAVE, REPLICATION CLIENT, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, CREATE USER, EVENT, TRIGGER, CREATE TABLESPACE

    # 示例
    ## 授权
    grant select,insert,update,delete on *.* to dev@'%' identified by '123';
    ## 回收权限
    revoke delete on *.* from dev@'%';

DQL:数据查询语言

拓展内容

聚合函数

1
2
3
4
5
6
# 聚合函数(MySQL中常用的)
max() # 求最大值函数
min() # 求最小值函数
avg() # 求平均值函数
sum() # 求和函数
count() # 统计函数

字符集

  • Linux:
    • utf-8:一个中文占3个字节
    • utf8mb4:一个中文占4个字节
  • Windows:GBK(国标扩) GB2312
  • 万国编码:unicode
  • 万国编码可以在各个字符集之间转换

校验规则

1
2
3
4
5
6
7
# 查看MySQL中所有的校验规则
show collation;
## ci # 大小写不敏感
## cs || bin # 大小写敏感

# 查看MySQL中所有的字符集
show charset;

统一字符集

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 操作系统
## CentOS6
vim /etc/sysconfig/i18n
LANG="en_US.UTF-8"
## CentOS7
vim /etc/locale.conf
LANG="en_US.UTF-8"

# 远程连接工具
Xshell字符集设置:如下图

# mysql的库
create database 库名 charset utf8;

# mysql的表
create table 表名(id int) charset utf8;

# 修改mysql配置文件
vim /etc/my.cnf
[mysqld]
character_set_server=utf8

image-20230703201317612

针对库的DQL

语法属性

1
2
3
4
5
6
7
8
9
10
11
# 查看所有数据库
show databases;

# 查看数据库的属性
show create database test_db;

# 查看当前所在数据库
select database();

# 查询数据库的错误日志
SHOW VARIABLES LIKE 'log_error';

针对用户的DQL

1
2
# 查用户权限
show grants for 用户@'主机域'

针对表的DQL

语法属性

1
2
3
4
5
6
7
8
9
10
11
# 查看当前库中的所有表
show tables;

# 查看指定库中的所有表
show tables from test_db;

# 查询建表语句
show create table 库名.表名;

# 查看表结构
desc 库名.表名;

针对表内容的DQL

Select 基础查询

语法属性

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
# 基础查询
select 字段 from 库名.表名;
select * from 库名.表名; # 危险:整张表的数据会占满内存

# 单条件查询
select 字段 from 库名.表名 where 字段='值';

# 多条件查询
select 字段 from 库名.表名 where 字段='值' or 字段='值';

# 范围查询( < , > , <= , >= , <> , != )
select 字段 from 库名.表名 where 字段 < 值;
select 字段 from 库名.表名 where 字段 > 值 and 字段 < 值;

# 模糊查询 like
select 字段 from 库名.表名 where 字段 like '%值%';
select 字段 from 库名.表名 where 字段 like '%值';
select 字段 from 库名.表名 where 字段 like '值%';

# 分页查询 limit
select 字段 from 库名.表名 limit 从指定条数开始显示,每页显示数据条数;

# 排序查询 order by
## 正序
select 字段 from 库名.表名 order by 字段;
## 倒序
select 字段 from 库名.表名 order by 字段 desc;

# 分组查询 group by
select 字段,聚合函数(字段) from 库名.表名 group by 字段;
## 公式
1.遇到统计想函数
2.形容词前groupby
3.函数中央是名词
4.列名select后添加

# 使用过的函数
password()
now()
database()

查询示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
# 查询表字段
show tables from world;
+-----------------+
| Tables_in_world |
+-----------------+
| city | # 城市表
| country | # 国家表
| countrylanguage | # 国家语言表
+-----------------+

# 查询表结构
desc world.city;
+-------------+----------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------------+----------+------+-----+---------+----------------+
| ID | int(11) | NO | PRI | NULL | auto_increment |
| Name | char(35) | NO | | | |
| CountryCode | char(3) | NO | MUL | | |
| District | char(20) | NO | | | |
| Population | int(11) | NO | | 0 | |
+-------------+----------+------+-----+---------+----------------+

# 查询所有数据
select * from world.city;

# 单条件查询
select * from world.city where countrycode='CHN';

# 多条件查询
select * from world.city where countrycode='CHN' or countrycode='USA';

# 国家代码是CHN的并且省市heillongjiang的城市名有哪些?
select name from world.city where countrycode='CHN' and district='heilongjiang';

# 范围查询 < 、> 、<= 、>= 、 <> 、!=
select * from world.city where id > 10 and id < 30;
select * from world.city where population < 1000;

# 模糊查询 like
select * from world.city where countrycode like '%B%';
select * from world.city where countrycode like '%B';
select * from world.city where countrycode like 'B%';

# 分页查询 limit
select * from world.city limit 0,65;
select * from world.city limit 65,65;
select * from world.city limit 130,65;

# 排序查询 order by
## 顺序
select * from world.city order by population;
## 倒序
select * from world.city order by population desc;
select id as '序号',name as '城市名',countrycode as '国家代码',district as '省',population as '人口数量'
from world.city order by population desc limit 10;

# 统计一张表有多少条数据
select count(*) from world.city;

# 分组查询 group by
## 统计世界上每个国家的总人口数(练习)
1.sum()
2.group by contrycode
3.sum(population)
4.select 国家代码 总人口数量
select countrycode,sum(population)
from world.city group by countrycode;

select countrycode,sum(population)
from world.city group by countrycode order by sum(population);

## 统计中国各个省的人口数量(练习)
1.sum()
2.group by district
3.sum(population)
4.select 国家代码 省 总人口数量
select countrycode,district,sum(population) from world.city where countrycode='CHN'group by district;

## 统每个国家的城市数量(练习)
1.count()
2.group by countrycode
3.count(name)
4.select 国家代码 城市数量
select countrycode,count(name) from world.city group by countrycode;

## 统计中国每个省的城市数量(练习)
1.count()
2.group by district
3.count(name)
4.select 国家代码 省 城市数量
select countrycode,district,count(name)
from world.city
where countrycode='CHN' group by district order by count(name);

Select 高级用法(连表查询)

连表查询分类

  • 传统连接
  • 自连接
  • 内连接
  • 外连接
    • 左外连接
    • 右外连接

连表查询-传统连接

  • 语法属性

    1
    2
    3
    4
    5
    6
    7
    8
    # 传统连接
    找等价条件 + 需求条件

    # 语法格式
    select 表1.字段1,表2.字段2
    from 表1,表2
    where 表1.等价字段=表2.等价字段
    and 条件字段='条件值';
  • 查询示例

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    # 找等价条件 + 需求条件
    select stu_name.name,stu_score.mark
    from stu_name,stu_score
    where stu_name.id=stu_score.id
    and name='zhang3';
    +--------+------+
    | name | mark |
    +--------+------+
    | zhang3 | 80 |
    +--------+------+

    # 世界上小于100人的人口城市是哪个国家的?
    select country.name as '国家名',city.name as '城市名',city.population as '城市人口'
    from city,country
    where city.countrycode=country.code
    and city.population<100;

    # 世界上小于100人的人口城市是哪个国家的他们说的语言是什么?
    select country.name,city.name,city.population,countrylanguage.language
    from city,country,countrylanguage
    where city.countrycode=country.code
    and countrylanguage.countrycode=country.code
    and city.population<100;
    +----------+-----------+------------+-------------+
    | name | name | population | language |
    +----------+-----------+------------+-------------+
    | Pitcairn | Adamstown | 42 | Pitcairnese |
    +----------+-----------+------------+-------------+

连表查询-自连接

  • 语法属性

    1
    2
    3
    4
    5
    6
    7
    # 自动连接(natural join)
    自动找到包含等价条件的列(大前提条件:多张表中,等价条件的列名,必须一致)

    # 语法格式
    select 表1.字段1,表2.字段2
    from 表1 natural join 表2
    where 条件字段='条件值';

    image-20230406161924578

  • 查询示例

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    # 双表自连接示例
    select stu_name.name,stu_score.mark
    from stu_name natural join stu_score
    where name='li4';
    +------+------+
    | name | mark |
    +------+------+
    | li4 | 50 |
    +------+------+

    # 双表自连接示例:世界上小于100人的人口城市是哪个国家的他们说的语言是什么?
    select city.countrycode,city.name,city.population,countrylanguage.language
    from city natural join countrylanguage
    where city.population<100;
    +-------------+-----------+------------+-------------+
    | countrycode | name | population | language |
    +-------------+-----------+------------+-------------+
    | PCN | Adamstown | 42 | Pitcairnese |
    +-------------+-----------+------------+-------------+

    # 三表自连接示例
    select stu_name.name,stu_score.mark,stu_age.age
    from stu_name natural join stu_score natural join stu_age
    where name='wang5';
    +-------+------+------+
    | name | mark | age |
    +-------+------+------+
    | wang5 | 70 | 40 |
    +-------+------+------+

连表查询-内连接

  • 语法属性

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    # 内连接(inter join on)
    A表 join B表 on 等价条件
    A表 join B表 on 等价条件1 join C表 on 等价条件2 # SQL-92标准
    注意:小表在前大表在后

    # 语法格式
    select 表1.字段1,表2.字段2,表2.字段3
    from 表1 join 表2
    on 表1.等价字段1=表2.等价字段2
    where 表.条件字段<100;
  • 查询示例

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    # 世界上小于100人的人口城市是哪个国家的?
    select country.name,city.name,city.population
    from city join country
    on city.countrycode=country.code
    where city.population<100;

    # 世界上小于100人的人口城市是哪个国家的他们说的语言是什么?
    select country.name,city.name,city.population,countrylanguage.language
    from city join country
    on city.countrycode=country.code
    join countrylanguage
    on countrylanguage.countrycode=country.code
    where city.population<100;

连表查询-外连接

  • 语法属性

    1
    # 外连接(outer join)
  • 左外连接

    • 语法属性

      1
      2
      3
      4
      5
      6
      7
      8
      # 左外连接(left outer join on)
      实际使用较少,主要运用在聊天软件隐藏部分信息

      # 语法格式
      select 表1.字段1,表1.字段2,表2.字段3
      from 表1 left join 表2
      on 表1.等价字段1=表2.等价字段2
      and 表.条件字段<100;
    • 语法示例

      1
      2
      3
      4
      5
      # 左外连接示例
      select city.name,city.countrycode,country.name
      from city left join country
      on city.countrycode=country.code
      and city.population<100 limit 10;
  • 右外连接

    • 语法属性

      1
      2
      3
      4
      5
      6
      7
      8
      # 右外连接(right outer join on)
      实际使用较少,主要运用在聊天软件隐藏部分信息

      # 语法格式
      select 表1.字段1,表1.字段2,表2.字段3
      from 表1 right join 表2
      on 表1.等价字段1=表2.等价字段2
      and 表.条件字段<100;
    • 语法示例

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      # 右外连接示例
      select city.name,city.countrycode,country.name
      from city right join country
      on city.countrycode=country.code
      and city.population<100 limit 10;

      select city.name,country.code,country.name
      from city right join country
      on city.countrycode=country.code
      and city.population<100 limit 10;

合并查询

  • 语法属性

    1
    2
    3
    4
    5
    # 合并查询(union all)
    联合查询,效率高

    # 语法格式
    select 字段 from 库.表 where 条件字段1='条件值1' union all select 字段 from 库.表 where 条件字段2='条件值1';
  • 语法示例

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    # 提升效率的高级用法
    select * from city where countrycode='CHN' or countrycode='USA';
    select * from city where countrycode in ('CHN','USA');

    # 联合查询,效率高于上面两种
    select * from city where countrycode='CHN' union all select * from city where countrycode='USA';

    # 对比效率
    explain select * from city where countrycode='CHN' union all select * from city where countrycode='USA';
    +----+-------------+-------+------------+------+
    | id | select_type | table | partitions | type |
    +----+-------------+-------+------------+------+
    | 1 | PRIMARY | city | NULL | ref |
    | 2 | UNION | city | NULL | ref |
    +----+-------------+-------+------------+------+

    explain select * from city where countrycode='CHN' or countrycode='USA';
    +----+-------------+-------+------------+-------+
    | id | select_type | table | partitions | type |
    +----+-------------+-------+------------+-------+
    | 1 | SIMPLE | city | NULL | range |
    +----+-------------+-------+------------+-------+

    explain select * from city where countrycode in ('CHN','USA');
    +----+-------------+-------+------------+-------+
    | id | select_type | table | partitions | type |
    +----+-------------+-------+------------+-------+
    | 1 | SIMPLE | city | NULL | range |
    +----+-------------+-------+------------+-------+

    # 全表扫描的效率最低
    explain select * from city;
    +----+-------------+-------+------------+------+
    | id | select_type | table | partitions | type |
    +----+-------------+-------+------------+------+
    | 1 | SIMPLE | city | NULL | ALL |
    +----+-------------+-------+------------+------+