【数据库】MySQL的左连接、右连接和全连接的实现
表student:
+----+-----------+------+
| id | name | age |
+----+-----------+------+
| 1 | Jim | 18 |
| 2 | Lucy | 16 |
| 3 | Lily | 16 |
| 4 | Lilei | 17 |
| 5 | Hanmeimei | 16 |
+----+-----------+------+
表mark:
+----+---------+-------+
| 1 | English | 90 |
| 1 | Math | 80 |
| 2 | English | 95 |
| 2 | Math | 70 |
| 3 | English | 70 |
| 3 | Math | 80 |
| 4 | English | 80 |
| 4 | Math | 80 |
| 8 | English | 90 |
| 8 | Math | 90 |
+----+---------+-------+
表info:
+----+----------+----------+
| id | city | district |
+----+----------+----------+
| 1 | nanjing | gulou |
| 2 | beijing | chaoyang |
| 3 | shanghai | pudong |
| 4 | hangzhou | xiaoshan |
| 5 | chengdu | wuhou |
| 6 | tianjing | hedong |
+----+----------+----------+
1.左连接:
(1)
SELECT student.id,mark.subject FROM student LEFT JOIN mark on student.id=mark.id;
查询结果:
+----+---------+
| id | subject |
+----+---------+
| 1 | English |
| 1 | Math |
| 2 | English |
| 2 | Math |
| 3 | English |
| 3 | Math |
| 4 | English |
| 4 | Math |
| 5 | NULL |
+----+---------+
(2)
SELECT student.id,mark.subject FROM student LEFT JOIN mark on student.id=mark.id where student.id<=4;
查询结果:
+----+---------+
| id | subject |
+----+---------+
| 1 | English |
| 1 | Math |
| 2 | English |
| 2 | Math |
| 3 | English |
| 3 | Math |
| 4 | English |
| 4 | Math |
+----+---------+
(3)
查询语句:select s.*,subject,score from student s left join mark m on s.id=m.id;
查询结果:
+----+-----------+------+---------+-------+
| id | name | age | subject | score |
+----+-----------+------+---------+-------+
| 1 | Jim | 18 | English | 90 |
| 1 | Jim | 18 | Math | 80 |
| 2 | Lucy | 16 | English | 95 |
| 2 | Lucy | 16 | Math | 70 |
| 3 | Lily | 16 | English | 70 |
| 3 | Lily | 16 | Math | 80 |
| 4 | Lilei | 17 | English | 80 |
| 4 | Lilei | 17 | Math | 80 |
| 5 | Hanmeimei | 16 | NULL | NULL |
+----+-----------+------+---------+-------+
(4)连接多个表时:
查询语句:SELECT s.*,subject,score,city,district FROM student s LEFT JOIN mark m ON s.id=m.id
LEFT JOIN info i ON s.id=i.id;
注意:要连接n个表就要有n-1个LEFT JOIN...ON 。
查询结果:
+----+-----------+-----+---------+-------+----------+----------+
| id | name | age | subject | score | city | district |
+----+-----------+-----+---------+-------+----------+----------+
| 1 | Jim | 18 | English | 90 | nanjing | gulou |
| 1 | Jim | 18 | Math | 80 | nanjing | gulou |
| 2 | Lucy | 16 | English | 95 | beijing | chaoyang |
| 2 | Lucy | 16 | Math | 70 | beijing | chaoyang |
| 3 | Lily | 16 | English | 70 | shanghai | pudong |
| 3 | Lily | 16 | Math | 80 | shanghai | pudong |
| 4 | Lilei | 17 | English | 80 | hangzhou | xiaoshan |
| 4 | Lilei | 17 | Math | 80 | hangzhou | xiaoshan |
| 5 | Hanmeimei | 16 | NULL | NULL | chengdu | wuhou |
+----+-----------+-----+---------+-------+----------+----------+
结论:左连接的结果集中包括左表(如(1)和(2)中的student)中符合where条件的所有行,如果左表中的某些行在右表中
没有与之匹配的(如student表中的id=5,name=Hanmeimei那行,在mark表并没有id=5与之匹配),则结果集中的右表中所选列
(如mark.subject)以null填充。可以有多个
2.右连接:
(1)
查询语句:SELECT student.id,mark.subject FROM student RIGHT JOIN mark on student.id=mark.id;
查询结果:
+------+---------+
| id | subject |
+------+---------+
| 1 | English |
| 1 | Math |
| 2 | English |
| 2 | Math |
| 3 | English |
| 3 | Math |
| 4 | English |
| 4 | Math |
| NULL | English |
| NULL | Math |
+------+---------+
(2)
查询语句:SELECT student.id,mark.subject FROM mark RIGHT JOIN student on student.id=mark.id;
查询结果:
+----+---------+
| id | subject |
+----+---------+
| 1 | English |
| 1 | Math |
| 2 | English |
| 2 | Math |
| 3 | English |
| 3 | Math |
| 4 | English |
| 4 | Math |
| 5 | NULL |
+----+---------+
结论:与左连接雷同。
3.MySQL不支持全外连接,所以只能采取关键字UNION来联合左、右连接的方法:
查询语句:SELECT s.*,subject,score FROM student s LEFT JOIN mark m ON s.id=m.id
UNION
SELECT s.*,subject,score FROM student s RIGHT JOIN mark m ON s.id=m.id;
查询结果:
+------+-----------+------+---------+-------+
| id | name | age | subject | score |
+------+-----------+------+---------+-------+
| 1 | Jim | 18 | English | 90 |
| 1 | Jim | 18 | Math | 80 |
| 2 | Lucy | 16 | English | 95 |
| 2 | Lucy | 16 | Math | 70 |
| 3 | Lily | 16 | English | 70 |
| 3 | Lily | 16 | Math | 80 |
| 4 | Lilei | 17 | English | 80 |
| 4 | Lilei | 17 | Math | 80 |
| 5 | Hanmeimei | 16 | NULL | NULL |
| NULL | NULL | NULL | English | 90 |
| NULL | NULL | NULL | Math | 90 |
+------+-----------+------+---------+-------+
结论:返回左右表的所有行。哪个表中没有的就用null填充。