【MySQL笔记】七种JOIN的SQL

准备数据

以一个简易问答系统为例,包括问题表和问题所属标签,问题表如下:

CREATE TABLE `t_qa` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `title` varchar(200) NOT NULL DEFAULT '' COMMENT '标题',
  `answer_count` int(5) unsigned NOT NULL DEFAULT '0' COMMENT '回答个数',
  `label_id` bigint(20) unsigned NOT NULL DEFAULT '0' COMMENT '标签id',
  `create_by` bigint(20) unsigned NOT NULL DEFAULT '0' COMMENT '创建人',
  `create_date` datetime NOT NULL DEFAULT '0000-00-00 00:00:00' COMMENT '创建时间',
  `update_by` bigint(20) unsigned DEFAULT NULL COMMENT '更新人',
  `update_date` datetime DEFAULT NULL COMMENT '更新时间',
  `del_flag` tinyint(1) unsigned NOT NULL DEFAULT '0' COMMENT '0:不删除,1:删除',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

INSERT INTO `t_qa` (`id`, `title`, `answer_count`, `label_id`, `create_by`, `create_date`, `update_by`, `update_date`, `del_flag`)
VALUES
    (1, 'Java是什么?', 5, 1, 0, '2017-08-24 17:43:53', 0, '2017-08-24 17:43:53', 0),
    (2, 'PHP是什么?', 4, 2, 0, '2017-08-24 17:43:53', 0, '2017-08-24 17:43:53', 0),
    (3, '前端是什么?', 3, 3, 0, '2017-08-24 17:43:53', 0, '2017-08-24 17:43:53', 0),
    (4, 'nodejs是什么?', 2, 0, 0, '2017-08-24 17:43:53', 0, '2017-08-24 17:43:53', 0),
    (5, 'css是什么?', 1, 0, 0, '2017-08-24 17:43:53', 0, '2017-08-24 17:43:53', 0),
    (6, 'JavaScript是什么?', 0, 0, 0, '2017-08-24 17:43:53', 0, '2017-08-24 17:43:53', 0);

标签表如下:

CREATE TABLE `t_label` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `name` varchar(50) NOT NULL DEFAULT '' COMMENT '名称',
  `create_by` bigint(20) unsigned NOT NULL DEFAULT '0' COMMENT '创建人',
  `create_date` datetime NOT NULL DEFAULT '0000-00-00 00:00:00' COMMENT '创建时间',
  `update_by` bigint(20) unsigned DEFAULT NULL COMMENT '更新人',
  `update_date` datetime DEFAULT NULL COMMENT '更新时间',
  `del_flag` tinyint(1) unsigned NOT NULL DEFAULT '0' COMMENT '0:不删除,1:删除',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

INSERT INTO `t_label` (`id`, `name`, `create_by`, `create_date`, `update_by`, `update_date`, `del_flag`)
VALUES
    (1, 'java', 0, '2017-08-24 17:43:53', 0, '2017-08-24 17:43:53', 0),
    (2, 'php', 0, '2017-08-24 17:43:53', 0, '2017-08-24 17:43:53', 0),
    (3, '大前端', 0, '2017-08-24 17:43:53', 0, '2017-08-24 17:43:53', 0),
    (4, 'mybatis', 0, '2017-08-24 17:43:53', 0, '2017-08-24 17:43:53', 0),
    (5, 'python', 0, '2017-08-24 17:43:53', 0, '2017-08-24 17:43:53', 0),
    (6, '多线程', 0, '2017-08-24 17:43:53', 0, '2017-08-24 17:43:53', 0);

一、左连接(LEFT JOIN)

图片描述

问题 回答个数 标签id 标签名称
Java是什么? 5 1 java
PHP是什么? 4 2 php
前端是什么? 3 3 大前端
nodejs是什么? 2 NULL NULL
css是什么? 1 NULL NULL
JavaScript是什么? 1 NULL NULL
SELECT 
    tq.title, tq.answer_count, tl.id, tl.name
FROM 
    t_qa tq LEFT JOIN t_label tl ON tq.label_id = tl.id

二、右连接(RIGHT JOIN)

图片描述

问题 回答个数 标签id 标签名称
Java是什么? 5 1 java
PHP是什么? 4 2 php
前端是什么? 3 3 大前端
NULL NULL 4 mybatis
NULL NULL 5 python
NULL NULL 6 多线程
SELECT 
    tq.title, tq.answer_count, tl.id, tl.name
FROM 
    t_qa tq RIGHT JOIN t_label tl ON tq.label_id = tl.id

三、内连接(INNER JOIN)

图片描述

问题 回答个数 标签id 标签名称
Java是什么? 5 1 java
PHP是什么? 4 2 php
前端是什么? 3 3 大前端
SELECT 
    tq.title, tq.answer_count, tl.id, tl.name
FROM 
    t_qa tq INNER JOIN t_label tl ON tq.label_id = tl.id

四、左独有连接(LEFT JOIN)

图片描述

问题 回答个数 标签id 标签名称
nodejs是什么? 2 NULL NULL
css是什么? 1 NULL NULL
JavaScript是什么? 0 NULL NULL
SELECT 
    tq.title, tq.answer_count, tl.id, tl.name
FROM 
    t_qa tq LEFT JOIN t_label tl ON tq.label_id = tl.id
WHERE
    tl.id IS NULL

五、右独有连接(RIGHT JOIN)

图片描述

问题 回答个数 标签id 标签名称
NULL NULL 4 mybatis
NULL NULL 5 python
NULL NULL 6 多线程
SELECT 
    tq.title, tq.answer_count, tl.id, tl.name
FROM 
    t_qa tq RIGHT JOIN t_label tl ON tq.label_id = tl.id
WHERE
    tq.label_id IS NULL

六、全连接(FULL JOIN)

图片描述

由于MySQL不支持FULL OUTER JOIN,所以如果有全连接需求时,可用表达式:full outer join = left outer join UNION right outer join来实现。

问题 回答个数 标签id 标签名称
Java是什么? 5 1 java
PHP是什么? 4 2 php
前端是什么? 3 3 大前端
nodejs是什么? 2 NULL NULL
css是什么? 1 NULL NULL
JavaScript是什么? 0 NULL NULL
NULL NULL 4 mybatis
NULL NULL 5 python
NULL NULL 6 多线程
SELECT tq.title, tq.answer_count, tl.id, tl.name FROM t_qa tq LEFT JOIN t_label tl ON tq.label_id = tl.id
UNION
SELECT tq.title, tq.answer_count, tl.id, tl.name FROM t_qa tq RIGHT JOIN t_label tl ON tq.label_id = tl.id 

七、全连接去交集(FULL JOIN)

图片描述

问题 回答个数 标签id 标签名称
nodejs是什么? 2 NULL NULL
css是什么? 1 NULL NULL
JavaScript是什么? 0 NULL NULL
NULL NULL 4 mybatis
NULL NULL 5 python
NULL NULL 6 多线程
SELECT tq.title, tq.answer_count, tl.id, tl.name FROM t_qa tq LEFT JOIN t_label tl ON tq.label_id = tl.id WHERE tl.id IS NULL
UNION
SELECT tq.title, tq.answer_count, tl.id, tl.name FROM t_qa tq RIGHT JOIN t_label tl ON tq.label_id = tl.id WHERE tq.label_id IS NULL

许剑锋的技术日常
记录我的学习、工作、生活中的珍贵点滴。
1 篇内容引用
413 声望
23 粉丝
0 条评论
推荐阅读
万字长文~vue+express+mysql带你彻底搞懂项目中的权限控制(附所有源码)
所谓的权限,其实指的就是:用户是否能看到,以及是否允许其对数据进行增删改查的操作,因为现在开发项目的主流方式是前后端分离,所以整个项目的权限是后端权限控制搭配前端权限控制共同实现的

水冗水孚7阅读 1k

分布式高可用Mysql数据库Percona XtraDB Cluster 8.0 与 Proxysql 史上最详尽用法指南
PXC是Percona XtraDB Cluster的缩写,是 Percona 公司出品的免费MySQL集群产品。PXC的作用是通过mysql自带的Galera集群技术,将不同的mysql实例连接起来,实现多主集群。在PXC集群中每个mysql节点都是可读可写的...

apollo0084阅读 7.1k评论 2

一次偶然机会发现的MySQL“负优化”
今天要讲的这件事和上述的两个sql有关,是数年前遇到的一个关于MySQL查询性能的问题。主要是最近刷到了一些关于MySQL查询性能的文章,大部分文章中讲到的都只是一些常见的索引失效场合,于是我回想起了当初被那个...

骑牛上青山5阅读 1k评论 3

MongoDB 插入时间与更新时间(create_time/update_time)
MongoDB 在数据库层面不能像 MySQL 一样设置自动创建 create_time/update_time,自动更新 update_time

qbit阅读 13.8k评论 2

Mysql索引覆盖
通常情况下,我们创建索引的时候只关注where条件,不过这只是索引优化的一个方向。优秀的索引设计应该纵观整个查询,而不仅仅是where条件部分,还应该关注查询所包含的列。索引确实是一种高效的查找数据方式,但...

京东云开发者2阅读 650

封面图
SegmentFault 思否技术周刊 Vol.70 — 深入 MySQL 实战
MySQL 软件采用了 GPL( GNU 通用公共许可证),由于其体积小、速度快、总体拥有成本低,尤其是开放源码这一特点,许多中小型网站为了降低网站总体拥有成本而选择了 MySQL 作为网站数据库。

Beverly2阅读 1.3k

封面图
MySQL 数据库索引技术原理初探
一本书 500 页的书,如果没有目录,直接去找某个知识点,可能需要找一会儿,但是借助前面的目录,就可以快速找到对应知识点在书的哪一页。这里的目录就是索引。

mylxsw1阅读 1.2k

413 声望
23 粉丝
宣传栏