参见MySQL(以5.1为例)中官方手册:MySQL官方手册-JOIN

假设有以下几个表

t1
id book
1 java
2 c++
3 php
t2
id author
2 zhang
3 wang
4 li
t3
author year
zhang 2003
ma 2006
liu 2011

Inner Join 内连接
将两个表中存在连接关系的字段,组成的记录集,叫做内连接。
内连接等价于

mysql> select t1.id as id,book,author from t1, t2 where t1.id=t2.id;
+------+------+--------+
| id | book | author |
+------+------+--------+
| 2 | c++ | zhang |
| 3 | php | wang |
+------+------+--------+
2 rows in set (0.00 sec)
mysql> select * from t1 inner join t2 using (id);
+------+------+--------+
| id | book | author |
+------+------+--------+
| 2 | c++ | zhang |
| 3 | php | wang |
+------+------+--------+
2 rows in set (0.00 sec)

可以看出,两者是等价的。没有Using子句的Inner Join相当于是求两个表的笛卡尔积。

Cross Join 交叉连接
在Mysql中,Cross Join可以用逗号表达式表示,例如(t1, t2)。在Mysql中,Cross Join 和 Inner Join 是等价的,但是在标准SQL中,它们并不等价,Inner Join 用于带有on表达式的连接,反之用Cross Join。以下两个SQL语句是等价的。
Cross Join 指的是两个table的笛卡尔积。以下三句SQL是等价的。

mysql> select * from t1 inner join t2;
mysql> select * from t1 cross join t2;
mysql> select * from (t1, t2);
mysql> select * from t1 nature join t2;
结果集:
+------+------+------+--------+
| id | book | id | author |
+------+------+------+--------+
| 1 | java | 2 | zhang |
| 2 | c++ | 2 | zhang |
| 3 | php | 2 | zhang |
| 1 | java | 3 | wang |
| 2 | c++ | 3 | wang |
| 3 | php | 3 | wang |
| 1 | java | 4 | li |
| 2 | c++ | 4 | li |
| 3 | php | 4 | li |
+------+------+------+--------+

下面两句SQL也是等价的。

mysql> select * from table1 left join (table2, table3) on (table2.id = table1.id and table2.author = table3.author);
mysql> select * from table1 left join (table2 cross join table3) on (table2.id = table1.id and table2.author = table3.author);
结果集:
+------+------+------+--------+--------+------+
| id | book | id | author | author | year |
+------+------+------+--------+--------+------+
| 1 | java | NULL | NULL | NULL | NULL |
| 2 | c++ | 2 | zhang | zhang | 2003 |
| 3 | php | NULL | NULL | NULL | NULL |
+------+------+------+--------+--------+------+

Natural Join 自然连接
NATURAL [LEFT] JOIN:这个句子的作用相当于INNER JOIN,或者是在USING子句中包含了联结的表中所有公共字段的Left JOIN(左联结)。
也就是说:下面两个SQL是等价的。

mysql> select * from table1 natural join table2;
mysql> select * from table1 inner join table2 using (id); 结果集:
+------+------+--------+
| id | book | author |
+------+------+--------+
| 2 | c++ | zhang |
| 3 | php | wang |
+------+------+--------+

同时,下面两个SQL也是等价的。

mysql> select * from table1 natural left join table2;
mysql> select * from table1 left join table2 using(id);
结果集:
+------+------+--------+
| id | book | author |
+------+------+--------+
| 1 | java | NULL |
| 2 | c++ | zhang |
| 3 | php | wang |
+------+------+--------+

  

 

Left Join 左外连接
左外连接A、B表的意思就是将表A中的全部记录和表B中字段连接形成的记录集,这里注意的是最后出来的记录集会包括表A的全部记录。
左连接表1,表二等价于右连接表二,表一。如下两个SQL是等价的:

mysql> select * from table1 left join table2 using (id);
mysql> select * from table2 right join table1 using (id);
结果集:
+------+------+--------+
| id | book | author |
+------+------+--------+
| 1 | java | NULL |
| 2 | c++ | zhang |
| 3 | php | wang |
+------+------+--------+

  

Right Join 右外连接

右外连接和左外连接是类似的。为了方便数据库便于访问,推荐使用左外连接代替右外连接。

Mysql表连接的一些注意事项:

1、两个表求差集的方法
如果求 左表 - 右表 的差集,使用类似下面的SQL:

SELECT left_tbl.* FROM left_tbl LEFT JOIN right_tbl ON left_tbl.id = right_tbl.id WHERE right_tbl.id IS NULL;
例如
mysql> select table1.* from table1 left join table2 using(id) where table2.id is null;
+------+------+
| id | book |
+------+------+
| 1 | java |
+------+------+
1 row in set (0.00 sec)

  

2、Using子句
Using子句可以使用On子句重写。但是使用Select * 查询出的结果有差别。以下两句话是等价的:

mysql> select id, book, author from table1 join table2 using (id);
mysql> select table1.id, book, author from table1 join table2 on table1.id=table2.id;
结果集:
+------+------+--------+
| id | book | author |
+------+------+--------+
| 2 | c++ | zhang |
| 3 | php | wang |
+------+------+--------+  

但是下面两个有些许不同,使用on时候,重复的部分会被输出两次。

mysql> select * from table1 join table2 using (id);
+------+------+--------+
| id | book | author |
+------+------+--------+
| 2 | c++ | zhang |
| 3 | php | wang |
+------+------+--------+
2 rows in set (0.00 sec)
mysql> select * from table1 join table2 on table1.id=table2.id;
+------+------+------+--------+
| id | book | id | author |
+------+------+------+--------+
| 2 | c++ | 2 | zhang |
| 3 | php | 3 | wang |
+------+------+------+--------+
2 rows in set (0.00 sec)

  

 

3、Straight Join的使用
STRAIGHT_JOIN 和 JOIN相似,除了大部分情况下,在使用STRAIGHT_JOIN时候,先读右表后读左表。而在大部分情况下是先读左表的。STRAIGHT_JOIN仅用于少数情况下的表连接性能优化,比如右表记录数目明显少于左表。

4、Mysql表连接的运算顺序
在MySQL 5.1版本中,INNER JOIN, CROSS JOIN, LEFT JOIN, 和RIGHT JOIN 比逗号表达式具有更高的优先级。
因此SQL1被解析成SQL3,而不是SQL2。

SQL1 : SELECT * FROM t1, t2 JOIN t3 ON (t1.i1 = t3.i3);
SQL2 : SELECT * FROM (t1, t2) JOIN t3 ON (t1.i1 = t3.i3);
SQL3 : SELECT * FROM t1, (t2 JOIN t3 ON (t1.i1 = t3.i3));  

因此会报错,找不到i1列。因此以后在写这样的查询的时候,最好写明白,不要省略括号,这样能避免很多错误。

5、循环的自然连接
在MySQL 5.1版本中,SQL1等价于SQL3, 而在MySQL以前版本中,SQL1等价于SQL2。

SQL1 : SELECT ... FROM t1 NATURAL JOIN t2 NATURAL JOIN t3;
SQL2 : SELECT ... FROM t1, t2, t3 WHERE t1.b = t2.b AND t2.c = t3.c;
SQL3 : SELECT ... FROM t1, t2, t3 WHERE t1.b = t2.b AND t2.c = t3.c AND t1.a = t3.a;
 

MySQL之Join的更多相关文章

  1. MySQL Left Join,Right Join

    魂屁,东西发这里了关于Left Join,Right Join的 在讲MySQL的Join语法前还是先回顾一下联结的语法,呵呵,其实连我自己都忘得差不多了,那就大家一起温习吧(如果内容有错误或有疑问, ...

  2. MySQL Full Join的实现

    MySQL Full Join的实现 由于MySQL不支持FULL JOIN,以下是替代方法 left join + union(可去除反复数据)+ right join select * from ...

  3. mysql left join

    MySQL左连接不同于简单连接.MySQL LEFT JOIN提供该表额外字段在左侧. 如果使用LEFT JOIN,得到的所有记录的匹配方式相同, 在左边表中得到的每个记录不匹配也会有一个额外的记录. ...

  4. MySQL的JOIN(一):用法

    JOIN的含义就如英文单词"join"一样,连接两张表,大致分为内连接,外连接,右连接,左连接,自然连接.这里描述先甩出一张用烂了的图,然后插入测试数据. CREATE TABLE ...

  5. MySQL的JOIN(三):JOIN优化实践之内循环的次数

    这篇博文讲述如何优化内循环的次数.内循环的次数受驱动表的记录数所影响,驱动表记录数越多,内循环就越多,连接效率就越低下,所以尽量用小表驱动大表.先插入测试数据. CREATE TABLE t1 ( i ...

  6. MySQL的JOIN(四):JOIN优化实践之快速匹配

    这篇博文讲述如何优化扫描速度.我们通过MySQL的JOIN(二):JOIN原理得知了两张表的JOIN操作就是不断从驱动表中取出记录,然后查找出被驱动表中与之匹配的记录并连接.这个过程的实质就是查询操作 ...

  7. MySQL的JOIN(五):JOIN优化实践之排序

    这篇博文讲述如何优化JOIN查询带有排序的情况.大致分为对连接属性排序和对非连接属性排序两种情况.插入测试数据. CREATE TABLE t1 ( id INT PRIMARY KEY AUTO_I ...

  8. Mysql Nested-Loop Join Algorithms

    MySQL在多表之间执行join时,利用一种nested-loop algorithm 或者其变种:(嵌套循环)  Nested-Loop Join Algorithm      一个简单的嵌套循环连 ...

  9. [转]MySQL update join语句

    原文地址:https://www.jianshu.com/p/f99665266bb1 在本教程中,您将学习如何使用MySQL UPDATE JOIN语句来执行跨表更新.我们将逐步介绍如何使用INNE ...

  10. mysql的join操作

    一.Join语法概述 join 用于多表中字段之间的联系,语法如下: ... FROM table1 INNER|LEFT|RIGHT JOIN table2 ON conditiona table1 ...

随机推荐

  1. 【CodeForces】【321E】Ciel and Gondolas

    DP优化/四边形不等式 这题……跟邮局那题简直一模一样吧……好水的E题…… 设dp[i][j]表示前 i 艘“gondola”坐了前 j 个人,那么方程即为$dp(i,j)=min\{ dp[i-1] ...

  2. 2014 ACM/ICPC Asia Regional Shanghai Online

    Tree http://acm.hdu.edu.cn/showproblem.php?pid=5044 树链剖分,区间更新的时候要用on的左++右--的标记方法,要手动扩栈,用c++交,综合以上的条件 ...

  3. Hibernate联合主键映射

    1.联合主键的映射规则 1) 类中的每个主键属性都对应到数据表中的每个主键列. Hibernate要求具有联合主键的实体类实现Serializable接口,并且重写hashCode与equals方法, ...

  4. iis express 启动多个网站

      iis express一次只能运行一个网站,  执行iisexpress 不加参数. 将执行配置文件中的第一个网站. iis express一次只能运行一个 应用程序池. 可以使用这个特点实现一次 ...

  5. 一个利用window.name实现的windowStorage

    //key:value|key:value var windowStorage = { _inited: false, _data: {}, init: function(str) { var tmp ...

  6. HDOJ 2069 Coin Change(母函数)

    Coin Change Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total ...

  7. Pytho中两种方式导入模块的差别

    1.使用import module,只是把模块导入,访问模块中的函数名或者是属性是必须使用点运算符(.)来访问,否则直接访问会提示找不到这些函数或者属性. 2.使用from numpy import ...

  8. nginx js、css多个请求合并为一个请求(concat模块)

    模块介绍 mod_concat模块由淘宝开发,目前已经包含在tengine中,并且淘宝已经在使用这个nginx模块.不过塔暂时没有包含在nginx中.这个模块类似于apache中的modconcat. ...

  9. jdom处理的XML Document 和String 之间的相互转化

    package util; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileWriter; ...

  10. ZOJ2923 Calculate Roads(SPFA上的dp)

    算是学了图dp后的第一次应用吧.题目其实真的是非常不严谨,什么都没说,基本靠猜,而且严格来说数据应该会有爆int的,不过不管那么多啦,思路对了就好- -0 #include<iostream&g ...