前一篇讲多表查询的时候讲过笛卡尔积,其实笛卡尔积就算一种连接,不过前一篇讲的时候并没有细说连接相关的内容,本篇就来详细说说表的连接有哪些。
本篇博客中主要用到的还是前一篇中的三张表:
雇员表emp:
部门表dept:
薪资等级表:
这三张表中没有明确指出外键和主键约束,但是是有外键和主键约束的样子的:
其中不同薪资对应不同的薪资等级。
这三张表就不细说了,等会用例子慢慢了解。
内连接实际上就是利用where子句对两种表形成的笛卡儿积进行筛选,我前面博客中的查询都是内连
接,这也是在开发过程中使用的最多的连接查询。
说一下语法:
select 字段 from 表1 inner join 表2 on 连接条件 and 其他条件;
这里的连接条件能用and不断级联。
我前一篇中所讲的语法格式和这里的语法格式不太一样,我前一篇对两个表进行连接的时候是这样(假如说是对emp表和dept表进行连接,如果看不懂建议先看一下我前一篇博客:【MySQL】多表查询、子查询、自连接、合并查询详解,包含大量示例,包你会):
两种语法产生的效果都是一样的。不过更推荐用inner join这个语法,至于为什么等会就知道了。
来个例子:
题目>>显示SMITH的名字和部门名称
所以说这是一个多表查询的问题,需要对这两张表进行连接:
但是这里没有添加连接条件,就会导致产生一些无效的记录。
比如说SMITH对应记录有三条,每条都有着不同的部门,但是SMITH实际上是属于20号部门的,对应dept连接出来的表中10和30号部门的信息没有用。故要去掉这些无效信息。
而emp表和dept表中共同列属性为deptno,需要根据deptno来对两张表进行连接,那么这两张表的连接条件就是二者的deptno要相等:
这样得到的记录就都是有效的记录了。
再加上题目的条件:SMITH的名字和部门名称,那么就是名字必须位SMITH:
不过这里的where也可以换成and:
因为员工名为SMITH也可以算成是一个连接的条件,不过把它算成筛选条件在逻辑上更通畅,所以用where更好一点,更能体现出来过程性。
如果用where,表达的意思就是先用deptno作为链接条件来对这两张表进行连接,连接好之后再用where对ename进行筛选,筛选出来的就是SMITH。逻辑更加清晰。
而用前一篇中的方法的话就会变成这样:
用的是where将表结构筛选出来。
逻辑上就是用on作为连接条件,用where作为筛选条件,更加清晰。
外连接可分为两种,左外连接和右外连接。
左外连接就是当两张表进行连接的时候左表所有的数据都要显示,就算右表对应行是没有数据的,也必须要将左表的所有数据显示出来,对应右表没有数据的行会显示为空。
两张表中的数据并不是所有都能一一对应上的,stu中id为3、4的在exam中没有成绩,而exam中id为11的在stu中没有数据。
左外连接的语法:
select 列名 from 表名1 left join 表名2 on 连接条件 and 其他连接条件;
此时如果将stu放到表名1,exam放到表名2:
此时stu中3、4没有成绩的也会显示出来,右表中对应列的数据为空。
对应id为11的在stu中没有数据,但是还是会将其显示,右表没有数据的会显示为空。
所以左外连接即在左表必须显示全,右表根据筛选条件连接,如果条件不满足就会显示为空。
来个题目:
题目>>查询所有学生的成绩,如果这个学生没有成绩,也要将学生的个人信息显示出来
和左外连接同理。右表中的数据必须完全显示。
其实有了左外连接都不需要右外连接了,因为我们在写sql语句的时候完全可以调整两个表名字的位置,这样就能起到同样的效果。
语法:
select 列名 from 表名1 right join 表名2 where 连接条件1 and 连接条件2 ...;
效果都是一样的。我甚至感觉左外连接看起来更方便一点。
很简单,不细说了。
题目>>对stu表和exam表联合查询,把所有的成绩都显示出来,即使这个成绩没有学生与它对应,也要显示出来
再来一个开头给出的三张表的例子:
题目>>列出部门名称和这些部门的员工信息,同时列出没有员工的部门
其实三dept表有4个部门,但是有一个部门没有员工,这个在生活中也是有的,比如说一个公司某项业务规模还比较小,但是不妨碍开一个空部门,等以后业务扩大了之后再向这个空部门中添加员工。
这样看起来就好多了。
到此结束。。。