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

复制代码
CREATE TABLE t_blog(
id INT PRIMARY KEY AUTO_INCREMENT,
title VARCHAR(50),
typeId INT
);
SELECT FROM t_blog;
+----+-------+--------+
| id | title | typeId |
+----+-------+--------+
| 1 | aaa | 1 |
| 2 | bbb | 2 |
| 3 | ccc | 3 |
| 4 | ddd | 4 |
| 5 | eee | 4 |
| 6 | fff | 3 |
| 7 | ggg | 2 |
| 8 | hhh | NULL |
| 9 | iii | NULL |
| 10 | jjj | NULL |
+----+-------+--------+
-- 博客的类别
CREATE TABLE t_type(
id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(20)
);
SELECT
FROM t_type;
+----+------------+
| id | name |
+----+------------+
| 1 | C++ |
| 2 | C |
| 3 | Java |
| 4 | C# |
| 5 | Javascript |
+----+------------+
复制代码
笛卡尔积:CROSS JOIN

要理解各种JOIN首先要理解笛卡尔积。笛卡尔积就是将A表的每一条记录与B表的每一条记录强行拼在一起。所以,如果A表有n条记录,B表有m条记录,笛卡尔积产生的结果就会产生n*m条记录。下面的例子,t_blog有10条记录,t_type有5条记录,所有他们俩的笛卡尔积有50条记录。有五种产生笛卡尔积的方式如下。

复制代码
SELECT FROM t_blog CROSS JOIN t_type;
SELECT
FROM t_blog INNER JOIN t_type;
SELECT FROM t_blog,t_type;
SELECT
FROM t_blog NATURE JOIN t_type;
select * from t_blog NATURA join t_type;
+----+-------+--------+----+------------+
| id | title | typeId | id | name |
+----+-------+--------+----+------------+
| 1 | aaa | 1 | 1 | C++ |
| 1 | aaa | 1 | 2 | C |
| 1 | aaa | 1 | 3 | Java |
| 1 | aaa | 1 | 4 | C# |
| 1 | aaa | 1 | 5 | Javascript |
| 2 | bbb | 2 | 1 | C++ |
| 2 | bbb | 2 | 2 | C |
| 2 | bbb | 2 | 3 | Java |
| 2 | bbb | 2 | 4 | C# |
| 2 | bbb | 2 | 5 | Javascript |
| 3 | ccc | 3 | 1 | C++ |
| 3 | ccc | 3 | 2 | C |
| 3 | ccc | 3 | 3 | Java |
| 3 | ccc | 3 | 4 | C# |
| 3 | ccc | 3 | 5 | Javascript |
| 4 | ddd | 4 | 1 | C++ |
| 4 | ddd | 4 | 2 | C |
| 4 | ddd | 4 | 3 | Java |
| 4 | ddd | 4 | 4 | C# |
| 4 | ddd | 4 | 5 | Javascript |
| 5 | eee | 4 | 1 | C++ |
| 5 | eee | 4 | 2 | C |
| 5 | eee | 4 | 3 | Java |
| 5 | eee | 4 | 4 | C# |
| 5 | eee | 4 | 5 | Javascript |
| 6 | fff | 3 | 1 | C++ |
| 6 | fff | 3 | 2 | C |
| 6 | fff | 3 | 3 | Java |
| 6 | fff | 3 | 4 | C# |
| 6 | fff | 3 | 5 | Javascript |
| 7 | ggg | 2 | 1 | C++ |
| 7 | ggg | 2 | 2 | C |
| 7 | ggg | 2 | 3 | Java |
| 7 | ggg | 2 | 4 | C# |
| 7 | ggg | 2 | 5 | Javascript |
| 8 | hhh | NULL | 1 | C++ |
| 8 | hhh | NULL | 2 | C |
| 8 | hhh | NULL | 3 | Java |
| 8 | hhh | NULL | 4 | C# |
| 8 | hhh | NULL | 5 | Javascript |
| 9 | iii | NULL | 1 | C++ |
| 9 | iii | NULL | 2 | C |
| 9 | iii | NULL | 3 | Java |
| 9 | iii | NULL | 4 | C# |
| 9 | iii | NULL | 5 | Javascript |
| 10 | jjj | NULL | 1 | C++ |
| 10 | jjj | NULL | 2 | C |
| 10 | jjj | NULL | 3 | Java |
| 10 | jjj | NULL | 4 | C# |
| 10 | jjj | NULL | 5 | Javascript |
+----+-------+--------+----+------------+
复制代码
内连接:INNER JOIN

内连接INNER JOIN是最常用的连接操作。从数学的角度讲就是求两个表的交集,从笛卡尔积的角度讲就是从笛卡尔积中挑出ON子句条件成立的记录。有INNER JOIN,WHERE(等值连接),STRAIGHT_JOIN,JOIN(省略INNER)四种写法。至于哪种好我会在MySQL的JOIN(二):优化讲述。示例如下。

复制代码
SELECT FROM t_blog INNER JOIN t_type ON t_blog.typeId=t_type.id;
SELECT
FROM t_blog,t_type WHERE t_blog.typeId=t_type.id;
SELECT FROM t_blog STRAIGHT_JOIN t_type ON t_blog.typeId=t_type.id; --注意STRIGHT_JOIN有个下划线
SELECT
FROM t_blog JOIN t_type ON t_blog.typeId=t_type.id;

+----+-------+--------+----+------+
| id | title | typeId | id | name |
+----+-------+--------+----+------+
|  1 | aaa   |      1 |  1 | C++  |
|  2 | bbb   |      2 |  2 | C    |
|  7 | ggg   |      2 |  2 | C    |
|  3 | ccc   |      3 |  3 | Java |
|  6 | fff   |      3 |  3 | Java |
|  4 | ddd   |      4 |  4 | C#   |
|  5 | eee   |      4 |  4 | C#   |
+----+-------+--------+----+------+

复制代码

左连接:LEFT JOIN

左连接LEFT JOIN的含义就是求两个表的交集外加左表剩下的数据。依旧从笛卡尔积的角度讲,就是先从笛卡尔积中挑出ON子句条件成立的记录,然后加上左表中剩余的记录(见最后三条)。

复制代码
SELECT * FROM t_blog LEFT JOIN t_type ON t_blog.typeId=t_type.id;

+----+-------+--------+------+------+
| id | title | typeId | id   | name |
+----+-------+--------+------+------+
|  1 | aaa   |      1 |    1 | C++  |
|  2 | bbb   |      2 |    2 | C    |
|  7 | ggg   |      2 |    2 | C    |
|  3 | ccc   |      3 |    3 | Java |
|  6 | fff   |      3 |    3 | Java |
|  4 | ddd   |      4 |    4 | C#   |
|  5 | eee   |      4 |    4 | C#   |
|  8 | hhh   |   NULL | NULL | NULL |
|  9 | iii   |   NULL | NULL | NULL |
| 10 | jjj   |   NULL | NULL | NULL |
+----+-------+--------+------+------+

复制代码

右连接:RIGHT JOIN

同理右连接RIGHT JOIN就是求两个表的交集外加右表剩下的数据。再次从笛卡尔积的角度描述,右连接就是从笛卡尔积中挑出ON子句条件成立的记录,然后加上右表中剩余的记录(见最后一条)。

复制代码
SELECT * FROM t_blog RIGHT JOIN t_type ON t_blog.typeId=t_type.id;

+------+-------+--------+----+------------+
| id   | title | typeId | id | name       |
+------+-------+--------+----+------------+
|    1 | aaa   |      1 |  1 | C++        |
|    2 | bbb   |      2 |  2 | C          |
|    3 | ccc   |      3 |  3 | Java       |
|    4 | ddd   |      4 |  4 | C#         |
|    5 | eee   |      4 |  4 | C#         |
|    6 | fff   |      3 |  3 | Java       |
|    7 | ggg   |      2 |  2 | C          |
| NULL | NULL  |   NULL |  5 | Javascript |
+------+-------+--------+----+------------+

复制代码
外连接:OUTER JOIN

外连接就是求两个集合的并集。从笛卡尔积的角度讲就是从笛卡尔积中挑出ON子句条件成立的记录,然后加上左表中剩余的记录,最后加上右表中剩余的记录。另外MySQL不支持OUTER JOIN,但是我们可以对左连接和右连接的结果做UNION操作来实现。

复制代码
SELECT FROM t_blog LEFT JOIN t_type ON t_blog.typeId=t_type.id
UNION
SELECT
FROM t_blog RIGHT JOIN t_type ON t_blog.typeId=t_type.id;

+------+-------+--------+------+------------+
| id   | title | typeId | id   | name       |
+------+-------+--------+------+------------+
|    1 | aaa   |      1 |    1 | C++        |
|    2 | bbb   |      2 |    2 | C          |
|    7 | ggg   |      2 |    2 | C          |
|    3 | ccc   |      3 |    3 | Java       |
|    6 | fff   |      3 |    3 | Java       |
|    4 | ddd   |      4 |    4 | C#         |
|    5 | eee   |      4 |    4 | C#         |
|    8 | hhh   |   NULL | NULL | NULL       |
|    9 | iii   |   NULL | NULL | NULL       |
|   10 | jjj   |   NULL | NULL | NULL       |
| NULL | NULL  |   NULL |    5 | Javascript |
+------+-------+--------+------+------------+

复制代码
USING子句

MySQL中连接SQL语句中,ON子句的语法格式为:table1.column_name = table2.column_name。当模式设计对联接表的列采用了相同的命名样式时,就可以使用 USING 语法来简化 ON 语法,格式为:USING(column_name)。
所以,USING的功能相当于ON,区别在于USING指定一个属性名用于连接两个表,而ON指定一个条件。另外,SELECT *时,USING会去除USING指定的列,而ON不会。实例如下。

复制代码
SELECT * FROM t_blog INNER JOIN t_type ON t_blog.typeId =t_type.id;
+----+-------+--------+----+------+
| id | title | typeId | id | name |
+----+-------+--------+----+------+
| 1 | aaa | 1 | 1 | C++ |
| 2 | bbb | 2 | 2 | C |
| 7 | ggg | 2 | 2 | C |
| 3 | ccc | 3 | 3 | Java |
| 6 | fff | 3 | 3 | Java |
| 4 | ddd | 4 | 4 | C# |
| 5 | eee | 4 | 4 | C# |
+----+-------+--------+----+------+

SELECT * FROM t_blog INNER JOIN t_type USING(typeId);
ERROR 1054 (42S22): Unknown column 'typeId' in 'from clause'
SELECT * FROM t_blog INNER JOIN t_type USING(id); -- 应为t_blog的typeId与t_type的id不同名,无法用Using,这里用id代替下。
+----+-------+--------+------------+
| id | title | typeId | name       |
+----+-------+--------+------------+
|  1 | aaa   |      1 | C++        |
|  2 | bbb   |      2 | C          |
|  3 | ccc   |      3 | Java       |
|  4 | ddd   |      4 | C#         |
|  5 | eee   |      4 | Javascript |
+----+-------+--------+------------+

复制代码
自然连接:NATURE JOIN

自然连接就是USING子句的简化版,它找出两个表中相同的列作为连接条件进行连接。有左自然连接,右自然连接和普通自然连接之分。在t_blog和t_type示例中,两个表相同的列是id,所以会拿id作为连接条件。
另外千万分清下面三条语句的区别 。
自然连接:SELECT FROM t_blog NATURAL JOIN t_type;
笛卡尔积:SELECT
FROM t_blog NATURA JOIN t_type;
笛卡尔积:SELECT * FROM t_blog NATURE JOIN t_type;

复制代码
SELECT * FROM t_blog NATURAL JOIN t_type;
SELECT t_blog.id,title,typeId,t_type.name FROM t_blog,t_type WHERE t_blog.id=t_type.id;
SELECT t_blog.id,title,typeId,t_type.name FROM t_blog INNER JOIN t_type ON t_blog.id=t_type.id;
SELECT t_blog.id,title,typeId,t_type.name FROM t_blog INNER JOIN t_type USING(id);

+----+-------+--------+------------+
| id | title | typeId | name       |
+----+-------+--------+------------+
|  1 | aaa   |      1 | C++        |
|  2 | bbb   |      2 | C          |
|  3 | ccc   |      3 | Java       |
|  4 | ddd   |      4 | C#         |
|  5 | eee   |      4 | Javascript |
+----+-------+--------+------------+SELECT * FROM t_blog NATURAL LEFT JOIN t_type;
SELECT t_blog.id,title,typeId,t_type.name FROM t_blog LEFT JOIN t_type ON t_blog.id=t_type.id;
SELECT t_blog.id,title,typeId,t_type.name FROM t_blog LEFT JOIN t_type USING(id);+----+-------+--------+------------+
| id | title | typeId | name       |
+----+-------+--------+------------+
|  1 | aaa   |      1 | C++        |
|  2 | bbb   |      2 | C          |
|  3 | ccc   |      3 | Java       |
|  4 | ddd   |      4 | C#         |
|  5 | eee   |      4 | Javascript |
|  6 | fff   |      3 | NULL       |
|  7 | ggg   |      2 | NULL       |
|  8 | hhh   |   NULL | NULL       |
|  9 | iii   |   NULL | NULL       |
| 10 | jjj   |   NULL | NULL       |
+----+-------+--------+------------+SELECT * FROM t_blog NATURAL RIGHT JOIN t_type;
SELECT t_blog.id,title,typeId,t_type.name FROM t_blog RIGHT JOIN t_type ON t_blog.id=t_type.id;
SELECT t_blog.id,title,typeId,t_type.name FROM t_blog RIGHT JOIN t_type USING(id);+----+------------+-------+--------+
| id | name       | title | typeId |
+----+------------+-------+--------+
|  1 | C++        | aaa   |      1 |
|  2 | C          | bbb   |      2 |
|  3 | Java       | ccc   |      3 |
|  4 | C#         | ddd   |      4 |
|  5 | Javascript | eee   |      4 |
+----+------------+-------+--------+

复制代码
补充

博客开头给出的第一张图除去讲了的内连接、左连接、右连接、外连接,还有一些特殊的韦恩图,这里补充一下。

复制代码
SELECT FROM t_blog LEFT JOIN t_type ON t_blog.typeId=t_type.id
WHERE t_type.id IS NULL;
+----+-------+--------+------+------+
| id | title | typeId | id | name |
+----+-------+--------+------+------+
| 8 | hhh | NULL | NULL | NULL |
| 9 | iii | NULL | NULL | NULL |
| 10 | jjj | NULL | NULL | NULL |
+----+-------+--------+------+------+
SELECT
FROM t_blog RIGHT JOIN t_type ON t_blog.typeId=t_type.id
WHERE t_blog.id IS NULL;
+------+-------+--------+----+------------+
| id | title | typeId | id | name |
+------+-------+--------+----+------------+
| NULL | NULL | NULL | 5 | Javascript |
+------+-------+--------+----+------------+
SELECT FROM t_blog LEFT JOIN t_type ON t_blog.typeId=t_type.id
WHERE t_type.id IS NULL
UNION
SELECT
FROM t_blog RIGHT JOIN t_type ON t_blog.typeId=t_type.id
WHERE t_blog.id IS NULL;
+------+-------+--------+------+------------+
| id | title | typeId | id | name |
+------+-------+--------+------+------------+
| 8 | hhh | NULL | NULL | NULL |
| 9 | iii | NULL | NULL | NULL |
| 10 | jjj | NULL | NULL | NULL |
| NULL | NULL | NULL | 5 | Javascript |
+------+-------+--------+------+------------+

转载于:https://blog.51cto.com/imork/2113877

MySQL的JOIN(一):用法相关推荐

  1. MySQL中JOIN的用法

    JOIN用于连表查询,主要有5种用法.下面分别演示这5种用法 随便建2张表,结构如下 字段col1用来使两张表有一个同名字段的(但其实没什么用,因为查询条件都需要用ON来指定,这里只是说明一下如果有相 ...

  2. mysql outer join的用法_MySQL 8 中的连接语法JOIN、OUTER JOIN的相关用法

    JOIN连接为内连接(INNER JOIN),如果A表与B表进行JOIN连接,都是查询这两个表的交集,所谓交集就是这条记录既在A表中存在也在B表中存在:mysql> SELECT a.id, a ...

  3. mysql outer join的用法_MySQL中join的用法

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

  4. MySQL的JOIN用法

    全文共925个字,10张图,预计阅读时间6分钟. 数据库中的JOIN称为连接,连接的主要作用是根据两个或多个表中的列之间的关系,获取存在于不同表中的数据.连接分为三类:内连接.外连接.全连接.另外还有 ...

  5. mysql中join on_Mysql inner join on的用法实例(必看)

    语法规则 SELECT column_name(s) FROM table_name1 INNER JOIN table_name2 ON table_name1.column_name=table_ ...

  6. mysql 联表比对,MySQL联表查询详解/超详细mysql left join,right join,inner join用法分析比较...

    超详细mysql left join,right join,inner join用法分析 下面是例子分析 表A记录如下: aID aNum 1 a20050111 2 a20050112 3 a200 ...

  7. mysql left join_MySQL LEFT JOIN 语法用法与实例

    MySQL LEFT JOIN 语法 SQL(MySQL) LEFT JOIN 会取得左表(table1)全部记录,即使右表(table2)并无对应匹配记录.LEFT JOIN 基本语法如下: ... ...

  8. mysql inner join_MySQL JOIN 语法说明与 INNER JOIN 语法用法实例

    MySQL JOIN 语法概述 SQL(MySQL) JOIN 用于根据两个或多个表中的字段之间的关系,从这些表中得到数据. JOIN 通常与 ON 关键字搭配使用,基本语法如下: ... FROM ...

  9. mysql natural join用法_MySQL NATURAL JOIN

    NATURAL JOIN 也叫自然连接,实际是属于 JOIN 的一种. MySQL NATURAL JOIN 语法如下: ... FROM table1 NATURAL JOIN table2 ... ...

最新文章

  1. 如何固化预训练模型的参数
  2. [Python]网络爬虫(二):利用urllib2通过指定的URL抓取网页内容
  3. Android --- This project contains Java compilation errors,which can cause rendering failures for
  4. 解决matplotlib中文乱码问题
  5. mysql优化概述4
  6. [云炬创业基础笔记]第五章创业机会评估测试13
  7. PreparedStatement和Statement比较
  8. BP神经网络相关知识
  9. linux在双系统中消失了,双系统重新安装windows后,ubuntu选项消失
  10. HighChart模拟点击series的name显示隐藏
  11. flex 布局,flex-grow 宽度未等比放大问题解决办法
  12. Linux系统中网络配置详解(一)
  13. 译: 6. 任务调度(定时执行任务)
  14. 小白教程:如何在MAC菜单栏上显示日期和时间
  15. Spring 菜鸟教程 IntrospectorCleanupListener
  16. 机器人手眼标定都能搞不定?快戳,最好用的手眼标定库!!!
  17. xt5 连接android auto,2021年凯迪拉克XT6将添加无线Apple CarPlay和Android Auto
  18. 2021年塔式起重机司机考试报名及塔式起重机司机免费试题
  19. python一对一辅导教程:Computational Problems for Physics chapter 1-A Code Listings 1.1 - 1.6
  20. Home键和返回键的区别

热门文章

  1. 栈、堆、方法区之间的关系
  2. python伪造邮件发件地址_python写一个邮箱伪造脚本
  3. PHP学习笔记-PHP语言基础1
  4. 人工智能实践:TensorFlow笔记学习(二)—— Python语法串讲
  5. 做网页需要学哪些计算机知识,网页美工设计需要掌握的电脑常识
  6. python 函数(二)
  7. MYSQL之SQL语句练习及思路_1
  8. python全栈 互联网协议
  9. JavaScript 函数声明,函数表达式,匿名函数,立即执行函数之区别
  10. bzoj3140: [Hnoi2013]消毒