SQL语句LEFT JOIN,RIGHT JOIN,INNER JOIN 的理解
环境MySQL
准备工作
- 创建表并插入数据
table_a
CREATE TABLE IF NOT EXISTS table_a (
`id` INT UNSIGNED PRIMARY KEY AUTO_INCREMENT ,
`parent_id` VARCHAR(100) NOT NULL,
`user_id` VARCHAR(100) NOT NULL,
`name` VARCHAR(100) NOT NULL DEFAULT 'table_a'
);
INSERT INTO table_a( `parent_id`, `user_id` )
VALUES
( 'parent_id_1','user_id');
INSERT INTO table_a( `parent_id`, `user_id` )
VALUES
( 'parent_id_2','user_id');
INSERT INTO table_a( `parent_id`, `user_id` )
VALUES
( 'surplus_a','surplus_a');
table_b
CREATE TABLE IF NOT EXISTS table_b (
`id` INT UNSIGNED PRIMARY KEY AUTO_INCREMENT ,
`parent_id` VARCHAR(100) NOT NULL,
`user_id` VARCHAR(100) NOT NULL,
`name` VARCHAR(100) NOT NULL DEFAULT 'table_b'
);
INSERT INTO table_b( `parent_id`, `user_id` )
VALUES
( 'parent_id_1','user_id');
INSERT INTO table_b( `parent_id`, `user_id` )
VALUES
( 'parent_id_2','user_id');
INSERT INTO table_b( `parent_id`, `user_id` )
VALUES
( 'surplus_b','surplus_b');
- 结果
table_a
id | parent_id | user_id | name |
---|---|---|---|
1 | parent_id_1 | user_id | table_a |
2 | parent_id_2 | user_id | table_a |
3 | surplus_a | surplus_a | table_a |
table_b
id | parent_id | user_id | name |
---|---|---|---|
1 | parent_id_1 | user_id | table_b |
2 | parent_id_2 | user_id | table_b |
3 | surplus_b | surplus_b | table_b |
3. 这里准备了 2 张表作为测试表,他们都有重复的数据,除了name字段
LEFT JOIN
- 测试
SELECT table_a.parent_id, table_a.user_id, table_a.name,
table_b.parent_id, table_b.user_id, table_b.name
FROM table_a
LEFT JOIN table_b on table_a.user_id = table_b.user_id;
- 结果
table_b
parent_id | user_id | name | parent_id | user_id | name |
---|---|---|---|---|---|
parent_id_1 | user_id | table_a | parent_id_1 | user_id | table_b |
parent_id_2 | user_id | table_a | parent_id_1 | user_id | table_b |
parent_id_1 | user_id | table_a | parent_id_2 | user_id | table_b |
parent_id_2 | user_id | table_a | parent_id_2 | user_id | table_b |
surplus_a | surplus_a | table_a | null | null | null |
- 结果分析
就此例而言
1、table_a和table_b的交集部分
LEFT JOIN 会按照table_b的每一行数据中user_id为准去匹配table_a的每一行,匹配到就会返回一行结果,匹配不到则不会返回。(换一种说法按照table_a的每一行数据中user_id为准去匹配table_b的每一行,匹配到就会返回一行结果,匹配不到则不会返回。两个方式结果都是一致的)
需要注意的是如果leftjoin的条件不具唯一性,按照上述规则会匹配除多条结果。
2、table_a和table_b的交集在table_a的补集部分
如果table_a中有未匹配到userid的行,也会返回,table_b自动补null。
RIGHT JOIN
- 结果分析
同LEFT JOIN 的结果分析,只是,table_a和table_b对调
INNER JOIN
- 测试
SELECT table_a.parent_id, table_a.user_id, table_a.name,
table_b.parent_id, table_b.user_id, table_b.name
FROM table_a
INNER JOIN table_b on table_a.user_id = table_b.user_id;
- 结果
parent_id | user_id | name | parent_id | user_id | name |
---|---|---|---|---|---|
parent_id_1 | user_id | table_a | parent_id_1 | user_id | table_b |
parent_id_2 | user_id | table_a | parent_id_1 | user_id | table_b |
parent_id_1 | user_id | table_a | parent_id_2 | user_id | table_b |
parent_id_2 | user_id | table_a | parent_id_2 | user_id | table_b |
- 结果分析
就此例而言,结果就是leftjoin或rightjoin中区交集的那一部分逻辑。
保证匹配规则的唯一性。
- 测试
SELECT table_a.parent_id, table_a.user_id, table_a.name,
table_b.parent_id, table_b.user_id, table_b.name
FROM table_a
INNER JOIN table_b on table_a.user_id = table_b.user_id AND table_a.parent_id = table_b.parent_id;
- 结果
parent_id | user_id | name | parent_id | user_id | name |
---|---|---|---|---|---|
parent_id_1 | user_id | table_a | parent_id_1 | user_id | table_b |
parent_id_2 | user_id | table_a | parent_id_2 | user_id | table_b |
- 结果分析
加上parent_id这个条件后,在两个表中,都只有唯一的行能够匹配,因此只匹配到了table_a和table_b对应的那一行,结果仅输出两行。