Kaynağa Gözat

0415编写多表操作文档

王立琳 3 yıl önce
ebeveyn
işleme
c1910f097d
1 değiştirilmiş dosya ile 260 ekleme ve 3 silme
  1. 260 3
      sql/04.multitable.md

+ 260 - 3
sql/04.multitable.md

@@ -1,7 +1,264 @@
 # 多表操作
 
-## 内连接
+关于 SQL 语句中的连接 (Join) 关键字,是较为常用而又不太容易理解的关键字,下面这个例子给出了一个简单的解释。
 
-## 外连接
+```sql
+--建表 table1,table2:
+create table table1(id int, name varchar(10))
+insert into table1 select 1, 'lee'
+insert into table1 select 2, 'zhang'
+insert into table1 select 4, 'wang'
+
+create table table2(id int, score int)
+insert into table2 select 1, 90
+insert into table2 select 2, 100
+insert into table2 select 3, 70
+```
+
+如表
+
+```
+	table1					|			table2
+------------------------------------------------------
+	id		name			|			id		score
+	1		lee				|			1		90
+	2		zhang			|			2		100
+	4		wang			|			3		70
+```
+
+以下均在查询分析器中执行
+
+## 一、内连接
+
+### 1、概念
+
+内联接是用比较运算符比较要联接列的值的联接(join 或 inner join)
+
+### 2、SQL 语句
+
+```sql
+select * from table1 inner join table2 on table1.id = table2.id
+```
+
+结果
+
+```
+	id		name		id		score
+----------------------------------------
+	1		lee			1		90
+	2		zhang		2		100
+```
+
+[^注释]: 只返回符合条件的 table1 和 table2 的列
+
+与下列执行效果相同
+
+```sql
+A: select a.*, b.* from table1 a, table2 b where a.id = b.id
+B: select * from table1 cross join table2 where table1.id = table2.id
+```
+
+[^注]: cross join 后加条件只能用 where,不能用 on
+
+## 二、外连接
+
+### 1、概念
+
+包括左向外联接、右向外联接或完整外部联接
+
+### 2、左连接:left join 或 left outer join
+
+(1)左向外联接的结果集包括 LEFT OUTER 子句中指定的左表的所有行,而不仅仅是联接列所匹配的行。如果左表的某行在右表中没有匹配行,则在相关联的结果集行中右表的所有选择列表列均为空值(null)。
+
+(2)SQL 语句
+
+```sql
+select * from table1 left join table2 on table1.id = table2.id
+```
+
+结果
+
+```
+	id		name		id		score
+------------------------------------------
+	1		lee			1		90
+	2		zhang		2		100
+	4		wang		NULL	NULL
+```
+
+[^注释]: 包含 table1 的所有子句,根据指定条件返回 table2 相应的字段,不符合的以 null 显示
+
+### 3、右连接:right join 或 right outer join
+
+(1)右向外联接是左向外联接的反向联接。将返回右表的所有行。如果右表的某行在左表中没有匹配行,则将为左表返回空值。
+
+(2)SQL 语句
+
+```sql
+select * from table1 right join table2 on table1.id = table2.id
+```
+
+结果
+
+```
+	id		name		id		score
+------------------------------------------
+	1		lee			1		90
+	2		zhang		2		100
+	NULL	NULL		3		70
+```
+
+[^注释]: 包含 table2 的所有子句,根据指定条件返回 table1 相应的字段,不符合的以 null 显示
+
+### 4、完整外部联接:full join 或 full outer join
+
+(1)完整外部联接返回左表和右表中的所有行。当某行在另一个表中没有匹配行时,则另一个表的选择列表列包含空值。如果表之间有匹配行,则整个结果集行包含基表的数据值。
+
+(2)SQL 语句
+
+```sql
+select * from table1 full join table2 on table1.id = table2.id
+```
+
+结果
+
+```
+	id		name		id		score
+------------------------------------------
+	1		lee			1		90
+	2		zhang		2		100
+	4		wang		NULL	NULL
+	NULL	NULL		3		70
+```
+
+[^注释]: 返回左右连接的和(见上左、右连接)
+
+## 三、交叉连接(完全)
+
+### 1、概念
+
+没有 where 子句的交叉联接将产生联接所涉及的表的笛卡尔积(cross join 不带条件 where)。第一个表的行数乘以第二个表的行数等于笛卡尔积结果集的大小。(table1 和 table2 交叉连接产生 3*3=9 条记录)
+
+### 2、SQL 语句
+
+```sql
+select * from table1 cross join table2
+```
+
+结果
+
+```
+	id		name		id		score
+------------------------------------------
+	1		lee			1		90
+	2		zhang		1		90
+	4		wang		1		90
+	1		lee			2		100
+	2		zhang		2		100
+	4		wang		2		100
+	1		lee			3		70
+	2		zhang		3		70
+	4		wang		3		70
+```
+
+[^注释]: 返回 3*3=9 条记录,即笛卡尔积
+
+等价(与下列执行效果相同)
+
+```sql
+A: select * from table1, table2 
+```
+
+## 三、多表更新、删除
+
+### 1、多表更新
+
+```sql
+--建表table3
+create table table3(id int, score int)
+insert into table3 select 1, null
+insert into table3 select 2, null
+insert into table3 select 3, null
+```
+
+如表
+
+```
+	table3
+---------------------
+	id		score
+	1		null
+	2		null
+	4		null
+```
+
+将 table2 中的 score 更新到 table3 中
+
+```sql
+update b set b.score = a.score from table2 a, table3 b where a.id = b.id
+```
+
+结果
+
+```
+	table3
+---------------------
+	id		score
+	1		90
+	2		100
+	4		70
+```
+
+### 2、多表删除
+
+```sql
+delete a from table1 a left join table2 b on a.id = b.id where b.id is null
+--等同于
+delete from table1 where not exists(select 1 from table2 b where table1.id = b.id)
+```
+
+删除前
+
+```
+	table1					|			table2
+------------------------------------------------------
+	id		name			|			id		score
+	1		lee				|			1		90
+	2		zhang			|			2		100
+	4		wang			|			3		70
+```
+
+删除后
+
+```
+	table1					|			table2
+------------------------------------------------------
+	id		name			|			id		score
+	1		lee				|			1		90
+	2		zhang			|			2		100
+							|			3		70
+```
+
+[^注释]: 将 table2 表中未使用的 table1 表编号删除
+
+
+
+```sql
+delete a from table1 a, table2 b where a.id = b.id
+--等同于
+delete from table1 where exists(select 1 from table2 b where table1.id = b.id)
+```
+
+结果
+
+```
+	table1					|			table2
+------------------------------------------------------
+	id		name			|			id		score
+	4		wang			|			1		90
+							|			2		100
+							|			3		70
+```
+
+[^注释]: 将 table2 表中使用的 table1 表编号删除
 
-## 多表更新、删除