【MySQL筆記】七種JOIN的SQL
準(zhǔn)備數(shù)據(jù)
以一個(gè)簡(jiǎn)易問答系統(tǒng)為例,包括問題表和問題所屬標(biāo)簽,問題表如下:
- CREATE TABLE `t_qa` (
- `id` bigint(20) NOT NULL AUTO_INCREMENT,
- `title` varchar(200) NOT NULL DEFAULT '' COMMENT '標(biāo)題',
- `answer_count` int(5) unsigned NOT NULL DEFAULT '0' COMMENT '回答個(gè)數(shù)',
- `label_id` bigint(20) unsigned NOT NULL DEFAULT '0' COMMENT '標(biāo)簽id',
- `create_by` bigint(20) unsigned NOT NULL DEFAULT '0' COMMENT '創(chuàng)建人',
- `create_date` datetime NOT NULL DEFAULT '0000-00-00 00:00:00' COMMENT '創(chuàng)建時(shí)間',
- `update_by` bigint(20) unsigned DEFAULT NULL COMMENT '更新人',
- `update_date` datetime DEFAULT NULL COMMENT '更新時(shí)間',
- `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);
標(biāo)簽表如下:
- 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 '創(chuàng)建人',
- `create_date` datetime NOT NULL DEFAULT '0000-00-00 00:00:00' COMMENT '創(chuàng)建時(shí)間',
- `update_by` bigint(20) unsigned DEFAULT NULL COMMENT '更新人',
- `update_date` datetime DEFAULT NULL COMMENT '更新時(shí)間',
- `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)
問題 | 回答個(gè)數(shù) | 標(biāo)簽id | 標(biāo)簽名稱 |
---|---|---|---|
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)
問題 | 回答個(gè)數(shù) | 標(biāo)簽id | 標(biāo)簽名稱 |
---|---|---|---|
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
三、內(nèi)連接(INNER JOIN)
問題 | 回答個(gè)數(shù) | 標(biāo)簽id | 標(biāo)簽名稱 |
---|---|---|---|
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
四、左獨(dú)有連接(LEFT JOIN)
問題 | 回答個(gè)數(shù) | 標(biāo)簽id | 標(biāo)簽名稱 |
---|---|---|---|
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
五、右獨(dú)有連接(RIGHT JOIN)
問題 | 回答個(gè)數(shù) | 標(biāo)簽id | 標(biāo)簽名稱 |
---|---|---|---|
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,所以如果有全連接需求時(shí),可用表達(dá)式:full outer join = left outer join UNION right outer join來實(shí)現(xiàn)。
問題 | 回答個(gè)數(shù) | 標(biāo)簽id | 標(biāo)簽名稱 |
---|---|---|---|
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)
問題 | 回答個(gè)數(shù) | 標(biāo)簽id | 標(biāo)簽名稱 |
---|---|---|---|
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