前几次面试的时候遇到左右连接的问题,这里进行回顾。
先通过下面两个表展示一下左连接和右连接的结果
左连接与右连接
员工表:
mysql> select * from employ;+-----------+------+------+| name | id | sal |+-----------+------+------+| 小王 | 1000 | 0 || 小李 | 1001 | 90 || 小华 | 1002 | NULL || xiaogui | 1008 | 3800 || xiaolang | 1009 | 3900 || xiaohu | 1003 | 4000 |+-----------+------+------+6 rows in set (0.00 sec)
学生表:
mysql> select * from student;+--------+------+------+| name | age | id |+--------+------+------+| 懒洋洋 | 10 | 1001 || 喜羊羊 | 100 | 1002 || 美羊羊 | 12 | NULL || 灰太狼 | NULL | 1004 |+--------+------+------+4 rows in set (0.00 sec)
左连接
mysql> select employ.sal,student.age from employ left join student on employ.id= student.id;+------+------+| sal | age |+------+------+| 0 | NULL || 90 | 10 || NULL | 100 || 3800 | NULL || 3900 | NULL || 4000 | NULL |+------+------+6 rows in set (0.00 sec)
右连接
mysql> select employ.sal,student.age from employ right join student on employ.id = student.id;+------+------+| sal | age |+------+------+| 90 | 10 || NULL | 100 || NULL | 12 || NULL | NULL |+------+------+4 rows in set (0.00 sec)
通过以上两个表我们总结如下:
左连接:以左边的表(employ)为主。显示左边表列的全部数据,如果右边表没有对应的数据,则为NULL
右连接:以右边的表(student)为主。显示右边表列的全部数据,如果左边表没有对应的数据,则为NULL
笛卡儿积
两个表的信息:
员工表:
mysql> select * from employ;+-----------+------+------+| name | id | sal |+-----------+------+------+| 小王 | 1000 | 0 || 小李 | 1001 | 90 || 小华 | 1002 | NULL || xiaogui | 1008 | 3800 || xiaolang | 1009 | 3900 || xiaohu | 1003 | 4000 |+-----------+------+------+6 rows in set (0.00 sec)
学生表:
mysql> select * from student;+--------+------+------+| name | age | id |+--------+------+------+| 懒洋洋 | 10 | 1001 || 喜羊羊 | 100 | 1002 || 美羊羊 | 12 | NULL || 灰太狼 | NULL | 1004 |+--------+------+------+4 rows in set (0.00 sec)
笛卡儿积的情况:
mysql> select * from employ, student;+-----------+------+------+--------+------+------+| name | id | sal | name | age | id |+-----------+------+------+--------+------+------+| 小王 | 1000 | 0 | 懒洋洋 | 10 | 1001 || 小王 | 1000 | 0 | 喜羊羊 | 100 | 1002 || 小王 | 1000 | 0 | 美羊羊 | 12 | NULL || 小王 | 1000 | 0 | 灰太狼 | NULL | 1004 || 小李 | 1001 | 90 | 懒洋洋 | 10 | 1001 || 小李 | 1001 | 90 | 喜羊羊 | 100 | 1002 || 小李 | 1001 | 90 | 美羊羊 | 12 | NULL || 小李 | 1001 | 90 | 灰太狼 | NULL | 1004 || 小华 | 1002 | NULL | 懒洋洋 | 10 | 1001 || 小华 | 1002 | NULL | 喜羊羊 | 100 | 1002 || 小华 | 1002 | NULL | 美羊羊 | 12 | NULL || 小华 | 1002 | NULL | 灰太狼 | NULL | 1004 || xiaogui | 1008 | 3800 | 懒洋洋 | 10 | 1001 || xiaogui | 1008 | 3800 | 喜羊羊 | 100 | 1002 || xiaogui | 1008 | 3800 | 美羊羊 | 12 | NULL || xiaogui | 1008 | 3800 | 灰太狼 | NULL | 1004 || xiaolang | 1009 | 3900 | 懒洋洋 | 10 | 1001 || xiaolang | 1009 | 3900 | 喜羊羊 | 100 | 1002 || xiaolang | 1009 | 3900 | 美羊羊 | 12 | NULL || xiaolang | 1009 | 3900 | 灰太狼 | NULL | 1004 || xiaohu | 1003 | 4000 | 懒洋洋 | 10 | 1001 || xiaohu | 1003 | 4000 | 喜羊羊 | 100 | 1002 || xiaohu | 1003 | 4000 | 美羊羊 | 12 | NULL || xiaohu | 1003 | 4000 | 灰太狼 | NULL | 1004 |+-----------+------+------+--------+------+------+24 rows in set (0.00 sec)
mysql> select count(*) from employ,student;+----------+| count(*) |+----------+| 24 |+----------+1 row in set (0.00 sec)
总结:两个表总共14数据,但我们得到了24条数据。这是什么情况?这就是笛卡儿积所产生的问题。笛卡儿积的具体执行过程看下图:
就像图中,employ表中有6项,student中有4项,6*4=24。所以左连接,右连接解决了笛卡儿积的问题。