mysql-join

连接的概念

连接分为条件连接、等值连接和自然连接三种。

  • 条件连接就是在多个表的笛卡尔积中选取满足条件的行的连接,例如 select * from A,B where A.a > A.b 之类的有条件的查询。
  • 等值连接就是特殊的条件连接,当条件为某字段=某字段时,即为等值连接。如SELECT ename,sal,dname FROM emp,dept WHERE emp.deptno=dept.deptno;
  • 自然连接是一种特殊的等值连接,他要求多个表有相同的属性字段,然后条件为相同的属性字段值相等,最后再将表中重复的属性字段去掉,即为自然连接。如A中a,b,c字段,B中有c,d字段,则select * from A natural join B 相当于 select A.a,A.b,A.c,B.d from A.c = B.c 。

Join操作基本分为3大类:外连接(细分为:左连接、右连接、全连接)、自然连接、内连接
Join操作的共性:第一步均为将所有参与操作的表进行了一个笛卡儿积,然后才依据各连接条件进行记录的筛选

内连接与等值连接的区别:

内连接:两个表(或连接)中某一数据项相等的连接称为内连接。等值连接一般用where字句设置条件,内连接一般用on字句设置条件,但内连接与等值连接效果是相同的。
内连接与等值连接其实是一回事情(等效)。
经常有人会问到selecta.id,b.namefrom a,b wherea.id=b.pid 与
selecta.id,b.namefrom a inner join b ona.id=b.pid 有什么区别,哪个效率更高一些。
实际上一回事情了。只是内连接是由SQL 1999规则定的书写方式。两个说的是一码事。

内连接与外连接的结果集区别:

假设我们有两张表。
Table A是左边的表。
Table B是右边的表。
其各有四条记录,其中有两条记录是相同的,如下所示:

id name id name
1 Pirate 1 Rutabaga
2 Monkey 2 Pirate
3 Ninja 3 Darth Vader
4 Spaghetti 4 Ninja

下面让我们来看看不同的Join会产生什么样的结果。

Inner join == A&B

产生的结果集中,是A和B的交集
SELECT * FROM TableA INNER JOIN TableB ON TableA.name = TableB.name

id name id name
1 Pirate 2 Pirate
3 Ninja 4 Ninja

Full outer join == A || B

SELECT * FROM TableA FULL OUTER JOIN TableB ON TableA.name = TableB.name

id name id name
1 Pirate 2 Pirate
2 Monkey null null
3 Ninja 4 Ninja
4 Spaghetti null null
null null 1 Rutabaga
null null 3 Darth Vader

产生A和B的并集。但是需要注意的是,对于没有匹配的记录,则会以null做为值。


Left outer join = A

产生表A的完全集,而B表中匹配的则有值,没有匹配的则以null值取代。
SELECT * FROM TableA LEFT OUTER JOIN TableB ON TableA.name = TableB.name

id name id name
1 Pirate 2 Pirate
2 Monkey null null
3 Ninja 4 Ninja
4 Spaghetti null null

A-B

SELECT * FROM TableA LEFT OUTER JOIN TableB ON TableA.name = TableB.name WHERE TableB.id IS null

id name id name
2 Monkey null null
4 Spaghetti null null

产生在A表中有而在B表中没有的集合。


A表和B表都没有出现的数据集

SELECT * FROM TableA FULL OUTER JOIN TableB ON TableA.name = TableB.name WHERE TableA.id IS null OR TableB.id IS null

id name id name
2 Monkey null null
4 Spaghetti null null
null null 1 Rutabaga
null null 3 Darth Vader

产生A表和B表都没有出现的数据集。


还需要注意的是我们还有一个是“交差集” cross join, 这种Join没有办法用文式图表示,因为其就是把表A和表B的数据进行一个N*M的组合,即笛卡尔积。表达式如下:
SELECT * FROM TableA CROSS JOIN TableB
这个笛卡尔乘积会产生 4 x 4 = 16 条记录,一般来说,我们很少用到这个语法。但是我们得小心,如果不是使用嵌套的select语句,一般系统都会产生笛卡尔乘积然再做过滤。这是对于性能来说是非常危险的,尤其是表很大的时候。

推荐阅读更多精彩内容

  • 什么是SQL数据库: SQL是Structured Query Language(结构化查询语言)的缩写。SQL是...
    大大大军阅读 1,194评论 0 10
  • 1.Left Outer Join左外连接 设数据库中有A、B两表,A和B有共同的交集C,当我们想查询出A的所有记...
    其实我很菜啊阅读 49评论 0 1
  • 1、MySQL启动和关闭(安装及配置请参照百度经验,这里不再记录。MySQL默认端口号:3306;默认数据类型格式...
    强壮de西兰花阅读 144评论 0 1
  • Student(S#,Sname,Sage,Ssex) 学生表 Course(C#,Cname,T#) 课程表 S...
    浮浮尘尘阅读 2,457评论 2 21
  • 梵高的信里提到:“每个人的心里都有一团火,路过的人只能看到烟,但是总有一个人,总有那么一个人能看到这火,然后走过来...
    走不停的苏阅读 125评论 0 2