在MySQL(以5.1为例)中,表连接的语法可以参见MySQL官方手册:MySQL官方手册-JOIN

在查询中,连接的语法类似

  1. SELECT select_expr FROM table_references

table_references(对表的引用)的定义如下(也可以看成连接表达式):(晕晕晕哈)

  1. table_references:
  2. table_reference [, table_reference] ...
  3. table_reference:
  4. table_factor
  5. | join_table
  6. table_factor:
  7. tbl_name [[AS] alias] [index_hint_list]
  8. | table_subquery [AS] alias
  9. | ( table_references )
  10. | { OJ table_reference LEFT OUTER JOIN table_reference
  11. ON conditional_expr }
  12. join_table:
  13. table_reference [INNER | CROSS] JOIN table_factor [join_condition]
  14. | table_reference STRAIGHT_JOIN table_factor
  15. | table_reference STRAIGHT_JOIN table_factor ON conditional_expr
  16. | table_reference {LEFT|RIGHT} [OUTER] JOIN table_reference join_condition
  17. | table_reference NATURAL [{LEFT|RIGHT} [OUTER]] JOIN table_factor
  18. join_condition:
  19. ON conditional_expr
  20. | USING (column_list)
  21. index_hint_list:
  22. index_hint [, index_hint] ...
  23. index_hint:
  24. USE {INDEX|KEY}
  25. [{FOR {JOIN|ORDER BY|GROUP BY}] ([index_list])
  26. | IGNORE {INDEX|KEY}
  27. [{FOR {JOIN|ORDER BY|GROUP BY}] (index_list)
  28. | FORCE {INDEX|KEY}
  29. [{FOR {JOIN|ORDER BY|GROUP BY}] (index_list)
  30. index_list:
  31. index_name [, index_name] ...

其中,table_factor是基本的表选择,而join_table是基于表的一些扩展。
下面,通过实验介绍一下表连接。
首先,假设有以下几个表

table1
book
1 java
2 c++
3 php
table2
author
2 zhang
3 wang
4 li
table3
year
zhang 2003
ma 2006
liu 2011

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

  1. mysql> select table1.id as id,book,author from table1, table2 where table1.id=table2.id;
  2. +------+------+--------+
  3. | id   | book | author |
  4. +------+------+--------+
  5. |    2 | c++  | zhang  |
  6. |    3 | php  | wang   |
  7. +------+------+--------+
  8. 2 rows in set (0.00 sec)
  9. mysql> select * from table1 inner join table2 using (id);
  10. +------+------+--------+
  11. | id   | book | author |
  12. +------+------+--------+
  13. |    2 | c++  | zhang  |
  14. |    3 | php  | wang   |
  15. +------+------+--------+
  16. 2 rows in set (0.00 sec)

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

  1. mysql> select * from table1 inner join table2;
  2. mysql> select * from table1 cross join table2;
  3. mysql> select * from (table1, table2);
  4. mysql> select * from table1 nature join table2;
  5. 结果集:
  6. +------+------+------+--------+
  7. | id   | book | id   | author |
  8. +------+------+------+--------+
  9. |    1 | java |    2 | zhang  |
  10. |    2 | c++  |    2 | zhang  |
  11. |    3 | php  |    2 | zhang  |
  12. |    1 | java |    3 | wang   |
  13. |    2 | c++  |    3 | wang   |
  14. |    3 | php  |    3 | wang   |
  15. |    1 | java |    4 | li     |
  16. |    2 | c++  |    4 | li     |
  17. |    3 | php  |    4 | li     |
  18. +------+------+------+--------+

不难理解,下面两句SQL也是等价的。

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

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

  1. mysql> select * from table1 natural join table2;
  2. mysql> select * from table1 inner join table2 using (id);
  3. 结果集:
  4. +------+------+--------+
  5. | id   | book | author |
  6. +------+------+--------+
  7. |    2 | c++  | zhang  |
  8. |    3 | php  | wang   |
  9. +------+------+--------+

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

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

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

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

Right Join 右外连接

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

最后,讲一下Mysql表连接的一些注意事项。

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

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

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

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

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

  1. mysql> select * from table1 join table2 using (id);
  2. +------+------+--------+
  3. | id   | book | author |
  4. +------+------+--------+
  5. |    2 | c++  | zhang  |
  6. |    3 | php  | wang   |
  7. +------+------+--------+
  8. 2 rows in set (0.00 sec)
  9. mysql> select * from table1 join table2 on table1.id=table2.id;
  10. +------+------+------+--------+
  11. | id   | book | id   | author |
  12. +------+------+------+--------+
  13. |    2 | c++  |    2 | zhang  |
  14. |    3 | php  |    3 | wang   |
  15. +------+------+------+--------+
  16. 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。

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

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

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

    1. SQL1 : SELECT ... FROM t1 NATURAL JOIN t2 NATURAL JOIN t3;
    2. SQL2 : SELECT ... FROM t1, t2, t3 WHERE t1.b = t2.b AND t2.c = t3.c;
    3. 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. 一张图告诉你为何必须学Python?

    互联网行业的薪资高.发展前景好,已经是人尽皆知的事了.越来越多的人对编程有了兴趣,想通过加入大公司实现人生逆袭,我们身边也涌现出了一些从零学习.变身大神的励志故事. 但更多的人还是选择观望:有人觉得编 ...

  2. 【DevExpress v17.2新功能预告】DevExtreme ASP.NET MVC新的强类型HTML Helpers

    在ASP.NET MVC中构建视图时,强类型HTML helpers非常有用.像@Html.TextBoxFor(m => m.FirstName)这样内置的Helper方法已经存在很长时间了, ...

  3. STL标准库-容器适配器

    技术在于交流.沟通,本文为博主原创文章转载请注明出处并保持作品的完整性 上一节介绍了仿函数适配器,这节主要介绍容器适配器和迭代器适配器的概念,其实容器适配器和迭代器其适配器就是封装了一些其他class ...

  4. L243 词汇题2009

    The applications of genetic engineering are abundant (plentiful) and choosing one appropriate for th ...

  5. 由pg_xlogdump统计信息想到的问题

    最近深入理解了Checkpoint的相关逻辑,再来看WAL日志的一些设置,又有了新的收获. 1.回顾pg_xlogdump出来的wal日志信息: 2.wal中FPI的占比很高问题分析: 3.重申ful ...

  6. IOS常用代码整理

    常用代码整理: 12.判断邮箱格式是否正确的代码: //利用正则表达式验证 -(BOOL)isValidateEmail:(NSString *)email { NSString *emailRege ...

  7. node 相关

    1. 更新npm : npm install npm -g / cnpm install npm -g 2.安装cnpm npm install -g cnpm --registry=https:// ...

  8. H - 【59】Lazier Salesgirl 模拟//lxm

    Kochiya Sanae is a lazy girl who makes and sells bread. She is an expert at bread making and selling ...

  9. 1.1 Linux中的进程 --fork、孤儿进程、僵尸进程、文件共享分析

    操作系统经典的三态如下: 1.就绪态 2.等待(阻塞) 3.运行态 其转换状态如下图所示: 操作系统内核中会维护多个队列,将不同状态的进程加入到不同的队列中,其中撤销是进程运行结束后,由内核收回. 以 ...

  10. opencv-python教程学习系列6-用滑动条做调色板

    前言 opencv-python教程学习系列记录学习python-opencv过程的点滴,本文主要介绍opencv-python用滑动条做调色板,坚持学习,共同进步. 系列教程参照OpenCV-Pyt ...