Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
檀越@新空间
Coding Tree
提交
5c247c03
C
Coding Tree
项目概览
檀越@新空间
/
Coding Tree
通知
2
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
C
Coding Tree
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
“b806e3fdbbc390bd7a095d65ebcfb5399d7afb81”上不存在“examples/C++/PaddleDetection/cascade_rcnn/test_client.py”
提交
5c247c03
编写于
4月 01, 2022
作者:
彭世瑜
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
fix
上级
dd646d35
变更
1
隐藏空白更改
内联
并排
Showing
1 changed file
with
360 addition
and
3 deletion
+360
-3
blog/php-mysql/sql-join.md
blog/php-mysql/sql-join.md
+360
-3
未找到文件。
blog/php-mysql/sql-join.md
浏览文件 @
5c247c03
...
@@ -9,9 +9,366 @@
...
@@ -9,9 +9,366 @@
-
交叉连接
-
交叉连接
-
内连接
-
内连接
-
外连接
-
外连接
-
左外链接(左连接)
-
左外链接(左连接)
-
右外连接(右连接)
-
右外连接(右连接)
-
自然连接
-
自然连接
## 2、交叉连接
将两张表的数据与另外一张表彼此交叉
### 2.1、原理
笛卡尔积
1.
从第一张表一次取出每一条数据
2.
取出每一条记录之后,与另外一张表的全部记录挨个匹配
3.
没有任何匹配条件,所有的结果都会保留
4.
记录数=第一张表记录数
\*
第二张表记录数
5.
字段数 = 第一张表字段数 + 第二章表字段数
### 2.2、基本语法
```
sql
表
1
cross
join
表
2
;
```
```
sql
mysql
>
select
*
from
tb_teacher
;
+
--------+------+
|
name
|
age
|
+
--------+------+
|
Jack
|
24
|
|
Tom
|
26
|
|
Steve
|
NULL
|
|
张三
|
23
|
|
张三
|
23
|
+
--------+------+
5
rows
in
set
(
0
.
00
sec
)
mysql
>
select
*
from
my_student
;
+
----+--------+----------+------+--------+
|
id
|
name
|
class_id
|
age
|
gender
|
+
----+--------+----------+------+--------+
|
1
|
刘备
|
1
|
18
|
2
|
|
2
|
李四
|
1
|
19
|
1
|
|
3
|
王五
|
2
|
20
|
2
|
|
7
|
张飞
|
2
|
21
|
1
|
|
8
|
关羽
|
1
|
22
|
2
|
|
9
|
曹操
|
1
|
20
|
NULL
|
+
----+--------+----------+------+--------+
6
rows
in
set
(
0
.
01
sec
)
mysql
>
select
*
from
my_student
cross
join
tb_teacher
;
+
----+--------+----------+------+--------+--------+------+
|
id
|
name
|
class_id
|
age
|
gender
|
name
|
age
|
+
----+--------+----------+------+--------+--------+------+
|
1
|
刘备
|
1
|
18
|
2
|
Jack
|
24
|
|
1
|
刘备
|
1
|
18
|
2
|
Tom
|
26
|
|
1
|
刘备
|
1
|
18
|
2
|
Steve
|
NULL
|
|
1
|
刘备
|
1
|
18
|
2
|
张三
|
23
|
|
1
|
刘备
|
1
|
18
|
2
|
张三
|
23
|
|
2
|
李四
|
1
|
19
|
1
|
Jack
|
24
|
|
2
|
李四
|
1
|
19
|
1
|
Tom
|
26
|
|
2
|
李四
|
1
|
19
|
1
|
Steve
|
NULL
|
|
2
|
李四
|
1
|
19
|
1
|
张三
|
23
|
|
2
|
李四
|
1
|
19
|
1
|
张三
|
23
|
|
3
|
王五
|
2
|
20
|
2
|
Jack
|
24
|
|
3
|
王五
|
2
|
20
|
2
|
Tom
|
26
|
|
3
|
王五
|
2
|
20
|
2
|
Steve
|
NULL
|
|
3
|
王五
|
2
|
20
|
2
|
张三
|
23
|
|
3
|
王五
|
2
|
20
|
2
|
张三
|
23
|
|
7
|
张飞
|
2
|
21
|
1
|
Jack
|
24
|
|
7
|
张飞
|
2
|
21
|
1
|
Tom
|
26
|
|
7
|
张飞
|
2
|
21
|
1
|
Steve
|
NULL
|
|
7
|
张飞
|
2
|
21
|
1
|
张三
|
23
|
|
7
|
张飞
|
2
|
21
|
1
|
张三
|
23
|
|
8
|
关羽
|
1
|
22
|
2
|
Jack
|
24
|
|
8
|
关羽
|
1
|
22
|
2
|
Tom
|
26
|
|
8
|
关羽
|
1
|
22
|
2
|
Steve
|
NULL
|
|
8
|
关羽
|
1
|
22
|
2
|
张三
|
23
|
|
8
|
关羽
|
1
|
22
|
2
|
张三
|
23
|
|
9
|
曹操
|
1
|
20
|
NULL
|
Jack
|
24
|
|
9
|
曹操
|
1
|
20
|
NULL
|
Tom
|
26
|
|
9
|
曹操
|
1
|
20
|
NULL
|
Steve
|
NULL
|
|
9
|
曹操
|
1
|
20
|
NULL
|
张三
|
23
|
|
9
|
曹操
|
1
|
20
|
NULL
|
张三
|
23
|
+
----+--------+----------+------+--------+--------+------+
30
rows
in
set
(
0
.
00
sec
)
```
### 2.3、应用
基本没有实际意义
等价于
```
sql
select
*
from
my_student
,
tb_teacher
;
```
## 3、内连接
从一张表中取出所有的记录,去另外一张表中匹配,利用匹配条件进行匹配,成功则保留,失败则放弃
### 3.1、原理
1.
从第一张表中取出一条记录,然后去另外一张表中进行匹配
2.
利用匹配条件进行匹配
3.
匹配到则保留,继续向下匹配
4.
匹配失败则放弃
### 3.2、基本语法
```
sql
表
1
inner
join
表
2
on
匹配条件
```
```
sql
create
table
my_class
(
id
int
primary
key
auto_increment
,
name
varchar
(
10
)
not
null
);
insert
into
my_class
(
name
)
values
(
'一班'
),
(
'二班'
);
mysql
>
select
*
from
my_class
;
+
----+--------+
|
id
|
name
|
+
----+--------+
|
1
|
一班
|
|
2
|
二班
|
+
----+--------+
mysql
>
select
*
from
my_student
;
+
----+--------+----------+------+--------+
|
id
|
name
|
class_id
|
age
|
gender
|
+
----+--------+----------+------+--------+
|
1
|
刘备
|
1
|
18
|
2
|
|
2
|
李四
|
1
|
19
|
1
|
|
3
|
王五
|
2
|
20
|
2
|
|
4
|
张飞
|
2
|
21
|
1
|
|
5
|
关羽
|
1
|
22
|
2
|
|
6
|
曹操
|
1
|
20
|
NULL
|
+
----+--------+----------+------+--------+
-- 如果内连接没有条件,其实就是交叉连接(笛卡尔积)
mysql
>
select
*
from
my_student
inner
join
my_class
;
+
----+--------+----------+------+--------+----+--------+
|
id
|
name
|
class_id
|
age
|
gender
|
id
|
name
|
+
----+--------+----------+------+--------+----+--------+
|
1
|
刘备
|
1
|
18
|
2
|
1
|
一班
|
|
1
|
刘备
|
1
|
18
|
2
|
2
|
二班
|
|
2
|
李四
|
1
|
19
|
1
|
1
|
一班
|
|
2
|
李四
|
1
|
19
|
1
|
2
|
二班
|
|
3
|
王五
|
2
|
20
|
2
|
1
|
一班
|
|
3
|
王五
|
2
|
20
|
2
|
2
|
二班
|
|
4
|
张飞
|
2
|
21
|
1
|
1
|
一班
|
|
4
|
张飞
|
2
|
21
|
1
|
2
|
二班
|
|
5
|
关羽
|
1
|
22
|
2
|
1
|
一班
|
|
5
|
关羽
|
1
|
22
|
2
|
2
|
二班
|
|
6
|
曹操
|
1
|
20
|
NULL
|
1
|
一班
|
|
6
|
曹操
|
1
|
20
|
NULL
|
2
|
二班
|
+
----+--------+----------+------+--------+----+--------+
12
rows
in
set
(
0
.
00
sec
)
-- 表的设计,通常会有同名字段,通常使用`表名.字段`来保证唯一性
mysql
>
select
*
from
my_student
inner
join
my_class
on
my_student
.
class_id
=
my_class
.
id
;
+
----+--------+----------+------+--------+----+--------+
|
id
|
name
|
class_id
|
age
|
gender
|
id
|
name
|
+
----+--------+----------+------+--------+----+--------+
|
1
|
刘备
|
1
|
18
|
2
|
1
|
一班
|
|
2
|
李四
|
1
|
19
|
1
|
1
|
一班
|
|
3
|
王五
|
2
|
20
|
2
|
2
|
二班
|
|
4
|
张飞
|
2
|
21
|
1
|
2
|
二班
|
|
5
|
关羽
|
1
|
22
|
2
|
1
|
一班
|
|
6
|
曹操
|
1
|
20
|
NULL
|
1
|
一班
|
+
----+--------+----------+------+--------+----+--------+
-- 如果表名比较长,可以使用别名简化
mysql
>
select
*
from
my_student
as
a
inner
join
my_class
b
on
a
.
class_id
=
b
.
id
;
+
----+--------+----------+------+--------+----+--------+
|
id
|
name
|
class_id
|
age
|
gender
|
id
|
name
|
+
----+--------+----------+------+--------+----+--------+
|
1
|
刘备
|
1
|
18
|
2
|
1
|
一班
|
|
2
|
李四
|
1
|
19
|
1
|
1
|
一班
|
|
3
|
王五
|
2
|
20
|
2
|
2
|
二班
|
|
4
|
张飞
|
2
|
21
|
1
|
2
|
二班
|
|
5
|
关羽
|
1
|
22
|
2
|
1
|
一班
|
|
6
|
曹操
|
1
|
20
|
NULL
|
1
|
一班
|
+
----+--------+----------+------+--------+----+--------+
-- 可以交换两张表的先后顺序
mysql
>
select
*
from
my_class
b
inner
join
my_student
as
a
on
a
.
class_id
=
b
.
id
;
+
----+--------+----+--------+----------+------+--------+
|
id
|
name
|
id
|
name
|
class_id
|
age
|
gender
|
+
----+--------+----+--------+----------+------+--------+
|
1
|
一班
|
1
|
刘备
|
1
|
18
|
2
|
|
1
|
一班
|
2
|
李四
|
1
|
19
|
1
|
|
2
|
二班
|
3
|
王五
|
2
|
20
|
2
|
|
2
|
二班
|
4
|
张飞
|
2
|
21
|
1
|
|
1
|
一班
|
5
|
关羽
|
1
|
22
|
2
|
|
1
|
一班
|
6
|
曹操
|
1
|
20
|
NULL
|
+
----+--------+----+--------+----------+------+--------+
-- on 可以使用 where 替换,推荐使用 on
mysql
>
select
*
from
my_class
b
inner
join
my_student
as
a
where
a
.
class_id
=
b
.
id
;
+
----+--------+----+--------+----------+------+--------+
|
id
|
name
|
id
|
name
|
class_id
|
age
|
gender
|
+
----+--------+----+--------+----------+------+--------+
|
1
|
一班
|
1
|
刘备
|
1
|
18
|
2
|
|
1
|
一班
|
2
|
李四
|
1
|
19
|
1
|
|
2
|
二班
|
3
|
王五
|
2
|
20
|
2
|
|
2
|
二班
|
4
|
张飞
|
2
|
21
|
1
|
|
1
|
一班
|
5
|
关羽
|
1
|
22
|
2
|
|
1
|
一班
|
6
|
曹操
|
1
|
20
|
NULL
|
+
----+--------+----+--------+----------+------+--------+
```
### 3.3、应用
内连接通常是在对数据有精确要求的地方使用,必须保证两张表中都能进行数据匹配,内连接匹配到才会保存
## 4、外连接
按照某一张表作为主表(表中所有记录在最后都会保留)根据条件取连接另外一张表,从而得到目标数据
外连接分为两种
-
左连接:左表是主表
-
右连接:右表是主表
### 4.1、原理
1.
确定主表,左连接就是左边的表为主表,右连接就是右边的表为主表
2.
拿主表的每一条记录,去匹配另外的一张表(从表)的每一条记录
3.
如果满足匹配条件,保留,不满足即不保留
4.
如果主表记录在从表中一条都没有匹配成功,那么也要保留记录, 从表对应的字段值都是null
### 4.2、基本语法
```
sql
-- 左连接
主表
left
join
从表
on
连接条件
;
-- 右连接
从表
right
join
主表
on
连接条件
;
```
左表的数据在前,右表的数据在后
```
sql
mysql
>
select
*
from
my_student
;
+
----+--------+----------+------+--------+
|
id
|
name
|
class_id
|
age
|
gender
|
+
----+--------+----------+------+--------+
|
1
|
刘备
|
1
|
18
|
2
|
|
2
|
李四
|
1
|
19
|
1
|
|
3
|
王五
|
2
|
20
|
2
|
|
4
|
张飞
|
2
|
21
|
1
|
|
5
|
关羽
|
1
|
22
|
2
|
|
6
|
曹操
|
1
|
20
|
NULL
|
+
----+--------+----------+------+--------+
mysql
>
select
*
from
my_class
;
+
----+--------+
|
id
|
name
|
+
----+--------+
|
1
|
一班
|
|
3
|
三班
|
|
2
|
二班
|
+
----+--------+
mysql
>
select
*
from
my_student
as
s
left
join
my_class
c
on
s
.
class_id
=
c
.
id
;
+
----+--------+----------+------+--------+------+--------+
|
id
|
name
|
class_id
|
age
|
gender
|
id
|
name
|
+
----+--------+----------+------+--------+------+--------+
|
1
|
刘备
|
1
|
18
|
2
|
1
|
一班
|
|
2
|
李四
|
1
|
19
|
1
|
1
|
一班
|
|
3
|
王五
|
2
|
20
|
2
|
2
|
二班
|
|
4
|
张飞
|
2
|
21
|
1
|
2
|
二班
|
|
5
|
关羽
|
1
|
22
|
2
|
1
|
一班
|
|
6
|
曹操
|
1
|
20
|
NULL
|
1
|
一班
|
+
----+--------+----------+------+--------+------+--------+
select
*
from
my_student
as
s
right
join
my_class
c
on
s
.
class_id
=
c
.
id
;
mysql
>
select
*
from
my_student
as
s
right
join
my_class
c
on
s
.
class_id
=
c
.
id
;
+
------+--------+----------+------+--------+----+--------+
|
id
|
name
|
class_id
|
age
|
gender
|
id
|
name
|
+
------+--------+----------+------+--------+----+--------+
|
1
|
刘备
|
1
|
18
|
2
|
1
|
一班
|
|
2
|
李四
|
1
|
19
|
1
|
1
|
一班
|
|
3
|
王五
|
2
|
20
|
2
|
2
|
二班
|
|
4
|
张飞
|
2
|
21
|
1
|
2
|
二班
|
|
5
|
关羽
|
1
|
22
|
2
|
1
|
一班
|
|
6
|
曹操
|
1
|
20
|
NULL
|
1
|
一班
|
|
NULL
|
NULL
|
NULL
|
NULL
|
NULL
|
3
|
三班
|
+
------+--------+----------+------+--------+----+--------+
```
### 4.3、特点
外连接中主表的数据一定会保存,连接之后不会出现记录数少于主表(内连接可能少数据)
左连接和右连接可以相互转换,但是数据对应的位置(字段顺序)会改变
### 4.4、应用
获取对应主表以及其他数据(关联)
通常使用左连接
## 5、using关键字
在连接查询中用来代替对应on关键字进行条件匹配
### 5.1、原理
1.
在连接查询时,使用on的地方用using代替
2.
使用using的前提是对应的两张表连接的字段名是同名的(类似自然连接)
3.
如果使用using关键字,那么对应的同名字段,最后在结果中只会保留一个
### 5.2、基本语法
```
sql
表
1
[
inner
,
left
,
right
]
join
表
2
using
(
同名字段列表
);
```
```
sql
select
*
from
my_student
left
join
my_class
using
(
class_id
);
-- 等价于
select
*
from
my_student
left
join
my_class
on
my_student
.
class_id
=
my_class
.
class_id
;
```
通常不使用
https://www.bilibili.com/video/BV1Vx411g7uJ?p=46&spm_id_from=pageDriver
https://www.bilibili.com/video/BV1Vx411g7uJ?p=42&spm_id_from=pageDriver
\ No newline at end of file
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录