多表联查(多表连接)(join

1、 分类

内连接、自然连接、外链接(左外连接、右外连接、全外连接(mysql不支持))

2、 内连接 inner join(等值连接,制定对应的等值条件)

SELECT * FROM emp,dept;/*得到的数据是不对的*/

得到的数据叫做笛卡尔积:结果是两个表数据的乘积

使用内连接去查

SELECT * FROM emp INNER JOIN dept;

结果依然是笛卡尔积,是因为我们没有制定对应的等值条件

SELECT * FROM emp e INNER JOIN dept d WHERE e.deptno = d.deptno;

/*emp.deptnodept.deptno这样的写法叫做:完全限定名

两个表中有相同的字段,类似于A村有个老张家,孩子叫张三

B村也有一个老张家,孩子也叫张三,

如果没有用到多表联查,就没有必要使用完全限定名,类似于

A村老张家的爸爸说,张三,吃饭了,指的是自己的孩子

用到了夺标联查,两家在一起,A村的老张家的爸爸说:张三,吃饭了

这个张三指的是谁?(不一定)

*/

提示:一般来讲,我们不使用内连接,因为效率低。用外链接

标准写法:select * from 1 别名1 inner join 2 别名2 where 别名1.xxx = 别名2.xxx;

SELECT * FROM emp e INNER JOIN dept d WHERE e.deptno = d.deptno;

 

方言写法:select * from 1 别名1,表2别名2 where别名1.xxx = 别名2.xxx;

SELECT * FROM emp e,dept d WHERE e.deptno = d.deptno;

 

3、 自然连接 natural(不需要指定等值条件)

select * from 1 别名1 natural join 2 别名2

4、 外链接(难点)

左外:select * from 1 别名1 left [ outer ] join 2 别名2 on 等值条件;

SELECT * FROM emp e LEFT OUTER JOIN dept d ON e.deptno = d.deptno;

左外的意思是:左表的记录无论是否满足条件,都会被查出来,而右表的记录只有满足条件的,才会被查出来。(左表中数据在右表中如果不存在,则右表的字段值为null

理解左外右外:

先看两个表数据:

 

 

/*左外*/

SELECT * FROM table1 t1 LEFT JOIN table2 t2 ON t1.id = t2.id;

 

左外连接是以左边的表为基准。通俗的讲,先把左表的数据全都显示出来,然后右边的表id与左边表的id的值是一样的,就拼接上去,比如说上面的id=1的数据,就拼接了。

如果没有匹配的,比如说id=2的数据,右边没有,用null拼接。

 

/*右外 */

SELECT * FROM table1 t1 RIGHT JOIN table2 t2 ON t1.id = t2.id;

 

右外跟左外的机制刚好相反。

如何去判断主副表?(左外连接:左边的是主表,右外连接:右边的是主表)

跟讲过的内连接做个简单的比较

SELECT * FROM table1 t1,table2 t2 WHERE t1.id = t2.id;

 

区别:内连接显示的是满足等值条件的记录,而外链接主表的记录都显示出来。

注意:使用多表联查,不一定要有外键。

例题:/*查询所有工作为文员的员工姓名及部门名称*/

SELECT e.ename,e.job,d.dname

FROM emp e LEFT JOIN dept d ON e.deptno = d.deptno

WHERE e.job = '文员';

 

例题:/*查询至少有一个员工的部门信息*/


结果很显然不对,因为40部门没人。

分析:因为我把dept作为主表,而主表的数据都显示,所以不合适,更改如下:

 

如下写法也可以

 

其实可以不用外链接,也可以查询

 

 

 

子查询

子查询:查询中还有查询(数select的个数)

1、 出现的位置

A from前:作为字段存在的

 

B where后:作为条件存在的

/*查询出工资高于在30部门工作的所有员工的工资的员工信息*/

 

C from后:表(极为罕见)

Logo

更多推荐