Mysql的七种join

对于SQL的Join,在学习起来可能是比较乱的。我们知道,SQL的Join语法有很多inner的,有outer的,有left的,有时候,对于Select出来的结果集是什么样子有点不是很清楚。Coding Horror上有一篇文章(实在不清楚为什么Coding Horror也被墙)通过 文氏图 Venn diagrams解释了SQL的Join。

贴个广告

楼主的博客已全部搬迁至自己的博客,感兴趣的小伙伴请移步haifeiWu与他朋友们的博客专栏

建表

在这里呢我们先来建立两张有外键关联的张表。

CREATE DATABASE db0206;
USE db0206;

CREATE TABLE `db0206`.`tbl_dept`(  
  `id` INT(11) NOT NULL AUTO_INCREMENT,
  `deptName` VARCHAR(30),
  `locAdd` VARCHAR(40),
  PRIMARY KEY (`id`)
) ENGINE=INNODB CHARSET=utf8;

CREATE TABLE `db0206`.`tbl_emp`(  
  `id` INT(11) NOT NULL AUTO_INCREMENT,
  `name` VARCHAR(20),
  `deptId` INT(11),
  PRIMARY KEY (`id`),
  FOREIGN KEY (`deptId`) REFERENCES `db0206`.`tb_dept`(`id`)
) ENGINE=INNODB CHARSET=utf8;
/*插入数据*/
INSERT INTO tbl_dept(deptName,locAdd) VALUES('RD',11);
INSERT INTO tbl_dept(deptName,locAdd) VALUES('HR',12);
INSERT INTO tbl_dept(deptName,locAdd) VALUES('MK',13);
INSERT INTO tbl_dept(deptName,locAdd) VALUES('MIS',14);
INSERT INTO tbl_dept(deptName,locAdd) VALUES('FD',15);

INSERT INTO tbl_emp(NAME,deptId) VALUES('z3',1);
INSERT INTO tbl_emp(NAME,deptId) VALUES('z4',1);
INSERT INTO tbl_emp(NAME,deptId) VALUES('z5',1);

INSERT INTO tbl_emp(NAME,deptId) VALUES('w5',2);
INSERT INTO tbl_emp(NAME,deptId) VALUES('w6',2);

INSERT INTO tbl_emp(NAME,deptId) VALUES('s7',3);

INSERT INTO tbl_emp(NAME,deptId) VALUES('s8',4);

文氏图与SQL语句的编写以及查询结果

内连接

内连接文氏图

表的内连接

执行的sql语句以及执行的查询结果
  • 执行的sql语句
select * from tbl_dept a inner join tbl_emp b on a.id=b.deptId;
  • 查询结果
    这里写图片描述

左外连接

左外连接文氏图

左连接

执行的sql语句以及执行的查询结果
  • 执行的sql语句
select * from tbl_dept a left join tbl_emp b on a.id=b.deptId;
  • 查询结果
    左外连接

右外连接

右外连接文氏图

这里写图片描述

执行的sql语句以及执行的查询结果
  • 执行的sql语句
select * from tbl_dept a right join tbl_emp b on a.id=b.deptId;
  • 查询结果
    这里写图片描述

左连接

左连接文氏图

这里写图片描述

执行的sql语句以及执行的查询结果
  • 执行的sql语句
elect * from tbl_dept a left join tbl_emp b on a.id=b.deptId where b.deptId is null;
  • 查询结果

这里写图片描述

右连接

右连接文氏图

右连接

执行的sql语句以及执行的查询结果
  • 执行的sql语句
select * from tbl_dept a right join tbl_emp b on a.id=b.deptId where a.id is null;
  • 查询结果

右连接

全连接

全连接文氏图

这里写图片描述

执行的sql语句以及执行的查询结果
  • 执行的sql语句
select * from tbl_dept a right join tbl_emp b on a.id=b.deptId 
union 
select * from tbl_dept a left join tbl_emp b on a.id=b.deptId;
  • 查询结果
    全连接

两张表中都没有出现的数据集

文氏图

执行的sql语句以及执行的查询结果
  • 执行的sql语句
select * from tbl_dept a right join tbl_emp b on a.id=b.deptId where a.id is null union select * from tbl_dept a left join tbl_emp b on a.id=b.deptId where b.deptId is null;
  • 查询结果

这里写图片描述

### MySQLJOIN七种类型及用法 #### 1. INNER JOIN (内连接) INNER JOIN 返回两个表中满足条件的记录。只有当两张表中的数据匹配时才会返回结果。 ```sql SELECT * FROM table1 t1 INNER JOIN table2 t2 ON t1.id = t2.id; ``` 这种类型的连接用于获取两表中共有的部分[^3]。 #### 2. LEFT JOIN (左外连接) LEFT JOIN 返回左边表格所有的记录以及右边表格中符合条件的记录;如果右边没有对应的数据,则显示NULL值。 ```sql SELECT * FROM table1 t1 LEFT JOIN table2 t2 ON t1.id = t2.id; ``` 此操作有助于保留左侧表的所有条目,即使右侧表不存在关联项也无妨[^1]。 #### 3. RIGHT JOIN (右外连接) RIGHT JOIN 是 LEFT JOIN 的镜像版本,它会返回右边表格所有的记录加上来自左边表格的相关联记录;如果没有找到对应的行则填充NULL。 ```sql SELECT * FROM table1 t1 RIGHT JOIN table2 t2 ON t1.id = t2.id; ``` 这种方式能够确保右侧表内的每一项都被展示出来,而不论左侧是否有相配对的信息存在。 #### 4. FULL OUTER JOIN (全外连接) 虽然标准SQL定义了FULL OUTER JOIN,但在MySQL里并不直接支持这一语法。不过可以通过组合使用UNION、LEFT JOIN 和 RIGHT JOIN 来实现相同的效果: ```sql SELECT col1, col2... FROM table1 t1 LEFT JOIN table2 t2 ON t1.id = t2.id UNION SELECT col1, col2... FROM table1 t1 RIGHT JOIN table2 t2 ON t1.id = t2.id; ``` 这种方法能获得两侧表完整的集合,即所有可能存在的关系都将被呈现给用户查看[^2]。 #### 5. CROSS JOIN (交叉连接) CROSS JOIN 不带任何ON子句的情况下会产生笛卡尔积——意味着第一个表里的每一个元素都会与第二个表中的每个成员形成一对组合。 ```sql SELECT * FROM table1 t1 CROSS JOIN table2 t2; ``` 这样的查询通常用来创建测试数据集或是其他需要遍历全部可能性的应用场合。 #### 6. SELF JOIN (自连接) SELF JOIN 表示同一张表内部之间的连接,常用于处理具有层次结构的数据模型,比如员工及其上级的关系链路。 ```sql SELECT a.*, b.* FROM employees AS a JOIN employees AS b ON a.manager_id = b.employee_id; ``` 这里展示了如何在一个实体的不同实例间建立联系,从而揭示出潜在模式或路径。 #### 7. NATURAL JOIN (自然连接) NATURAL JOIN 自动基于同名列名来进行匹配,并自动执行等价比较运算符的操作。需要注意的是,在实际应用中应谨慎对待该方式因为可能会带来意外的结果除非列名称非常明确唯一。 ```sql SELECT * FROM table1 t1 NATURAL JOIN table2 t2; ``` 尽管看起来简单方便,但由于缺乏显式的控制机制所以建议仅限于那些确实拥有共同字段并且含义一致的情况之下采用。
评论 3
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值