【Mysql数据库从0到1】-入门基础篇--mysql 多表查询
- 🔻一、mysql 多表查询
- 1.1 🍃 7种sql joins 的实现
- 1.2 🍃 错误写法---笛卡尔积错误
- 1.3 🍃 正确的多表`select`写法
- 🔻二、内连接`( inner) join`
- 🔻三、 外连接(`outer join`)
- 3.1 🌴 左外连接 ---`left (outer) join`
- 3.2 🌴 右外连接 ---`right (outer) join`
- 3.3 🌴 全外连接 --- `full (outer) join`
- 🔻四、 交叉连接(笛卡尔积)---`cross join`
- 🔻五、总结—温故知新
🔻一、mysql 多表查询
多表查询也称关联查询,几个表之间关联查询。
前提:表之间有关联字段。
1.1 🍃 7种sql joins 的实现
1.2 🍃 错误写法—笛卡尔积错误
- 省略多个表连接查询条件
- 连接条件无效
- 所有表中所有行相互连接
###查询每个角色对应的菜单--每个角色都与每个菜单id匹配了一遍
mysql> select t_role.id ,role_name,menu_id from t_role ,t_permission;
笛卡儿积:
1.3 🍃 正确的多表select
写法
为了避免笛卡尔积错误,需要在where
子句中加入有效的连接条件。
- 如果查询语句中出现了多个表中相同的字段,必须指明该字段所属的表
- 从sql优化的角度,建议多表查询时,每个字段前都指明其所属的表
- 可以在
select
和where
子句中使用表别名,增强sql可读性(from table1 表别名,table2 表别名
) - 如果使用了别名,则不能再使用表的原名
- 如果有
n
个表连接查询,则至少需n-1
个连接条件
###添加两个表的连接条件
####语法
select table1.colum , table2.colum from table1,table2 where table1.colum1 = table2.colum1;
mysql> select t_role.id ,role_name,menu_id from t_role ,t_permission where t_role.id = t_permission.role_id;
🔻二、内连接( inner) join
- 内连接也叫连接,是最早的一种连接。也称为普通连接或者自然连接
- 显示两个以上表的公共部分,如: 查询AB两个表的交集,只返回两个表中连接字段相等的行
inner join
或者join
(等同于inner join
),注:inner
关键字可以省略- sql 92语法:使用
+
号,如oracle数据库:select * from 表A ,表B on 表A.key=表B.key(+)
- sql 99语法:使用
join ...on
(mysql支持)
####语法
select * from 表A inner join 表B on 表A.key=表B.key;
或
select * from 表A join 表B on 表A.key=表B.key;
####如:查询t_role 与t_permission 连接字段相等的行,结果为两个表的交集
mysql> select t_role.id ,role_name,menu_id from t_role inner join t_permission on t_role.id = t_permission.role_id;
mysql>
🔻三、 外连接(outer join
)
- 外连接(
outer join
)分为三种:左外连接,右外连接,全外连接。对应sql:left / right / full outer join
。通常省略outer
这个关键字。 - 如果是
左外连接
,则连接条件中的左表
为主表,右表
为从表。 - 如果是
右外连接
,则连接条件中的右表
为主表,左表
为从表。 - 返回左右表中
不满足条件的行
,没有匹配行时,用null
值填充。
3.1 🌴 左外连接 —left (outer) join
- 左外连接也称左连接,返回左表中的所有记录和右表中连接字段相等的记录。
🌺 A表的全集+AB表的交集
:
- 左外连接 + A∩B
- 返回左表中的所有记录和右表中连接字段相等的记录
####语法####
select * from 表A left Join 表B on 表A.key=表B.key;
###如:查询所有角色对应的菜单权限,返回所有t_role行 ,和t_permission 连接字段相等的记录,没有匹配行时,右表列值用`null`值填充
mysql> select t_role.id ,role_name,menu_id from t_role left join t_permission on t_role.id = t_permission.role_id;
🌺 A表的全集-AB表的交集
:
- 左外连接 - A∩B
- 表示返回数据集为A的独有
#####语法##
select * from 表A left Join 表B on 表A.key=表B.key where 表B.key is null;
如:查询t_role角色对应的菜单权限,返回所有t_role独有的行
mysql> select t_role.id ,role_name,menu_id from t_role left join t_permission on t_role.id = t_permission.role_id where t_permission.role_id is null;
+----+-----------+---------+
| id | role_name | menu_id |
+----+-----------+---------+
| 18 | 老师 | NULL |
+----+-----------+---------+
1 row in set (0.00 sec)
mysql>
3.2 🌴 右外连接 —right (outer) join
- 右外连接也称右连接,返回右表中的所有记录和左表中连接字段相等的记录。
🌺 B表的全集+ AB表的交集
:
- 右外连接 + A∩B
- 返回右表中的所有记录和左表中连接字段相等的记录
####语法####
select * from 表A right Join 表B on 表A.key=表B.key;
####如:查询所有菜单权限对应的角色,返回所有t_permission行,和t_role 连接字段相等的记录,没有匹配行时,左表列值用`null`值填充
mysql> select t_role.id ,role_name,menu_id from t_role right join t_permission on t_role.id = t_permission.role_id;
🌺 B表的全集-AB表的交集
:
- 右外连接 - A∩B
- 表示返回数据集为B的独有
#####语法##
select * from 表A left Join 表B on 表A.key=表B.key where 表A.key is null;
如:查询t_role角色对应的菜单权限,返回所有t_permission独有的行
mysql> select t_role.id ,role_name,menu_id from t_role left join t_permission on t_role.id = t_permission.role_id where t_role.id is null;
mysql>
3.3 🌴 全外连接 — full (outer) join
- mysql本身不支持
full (outer) join
(全外连接),但可以通过union来实现。 - 语法一:
左外连接 + A∩B
union all
右外连接 - A∩B
- 语法二:
右外连接 + A∩B
union all
左外连接 - A∩B
### 语法一 ###
mysql> select t_role.id ,role_name,menu_id from t_role left join t_permission on t_role.id = t_permission.role_id
-> union all
-> select t_role.id ,role_name,menu_id from t_role left join t_permission on t_role.id = t_permission.role_id where t_role.id is null;
### 语法二 ###
mysql> selectt_role.id ,role_name,menu_id from t_role right join t_permission on t_role.id = t_permission.role_id
-> union all
-> select t_role.id ,role_name,menu_id from t_role left join t_permission on t_role.id = t_permission.role_id where t_permission.role_id is null;
union all
—返回查询结果并集,重复部分不去重
,执行union all
所需要的资源比union
少,如果结果数据不存在重复记录或不需要去重,则尽量使用union all
,以便提高查询效率。
union
—返回查询结果并集,去除重复部分
。
🌺 A+B-(AB交集)
:
-语法:左外连接 - A∩B union all 右外连接 - A∩B
###语法####
左外连接 - A∩B union all 右外连接 - A∩B
```sql
mysql> select t_role.id ,role_name,menu_id from t_role left join t_permission on t_role.id = t_permission.role_id where t_permission.role_id is null
-> union all
-> select t_role.id ,role_name,menu_id from t_role left join t_permission on t_role.id = t_permission.role_id where t_role.id is null;
+----+-----------+---------+
| id | role_name | menu_id |
+----+-----------+---------+
| 18 | 老师 | NULL |
+----+-----------+---------+
1 row in set (0.00 sec)
mysql>
🔻四、 交叉连接(笛卡尔积)—cross join
- 返回被连接的两个以上表所有数据行的笛卡尔积。
- 返回结果集合中的数据行数等于第一个表中复合查询条件的数据行数乘以第二个表中符合查询条件的数据行数。
####语法###
select * from 表A cross join 表B on 表A.key=表B.key;
mysql> select t_role.id ,role_name,menu_id from t_role cross join t_permission on t_role.id = t_permission.role_id;
🔻五、总结—温故知新
❓ 7种sql joins 的实现
❓ 内连接`( inner) join`语法
❓ 外连接(`outer join`)各种语法
❓ 交叉连接(笛卡尔积)---`cross join`语法
👈【上一篇】 |
💖The End💖 点点关注,收藏不迷路💖
| 【下一篇】👉 |