数据库(4)多表联合查询

二、多表联合查询

 1、合并结果集  : 把两个select语句的查询结果合并到一起

          union 合并结果集并且去除重复数据。

          union all合并结果集并且不去除重复数据 

要求:被合并的两个结果集,列数和列类型必须相同

2、连接查询  :  就是求多个表的乘积

例如   a表连接b 表那么查询结果就是a表*b表

连接查询产生 笛卡尔积(在sql 中实现方式,交叉连接 cross join)

所有的连接方式都会产生笛卡尔积,然后加上限制条件,才会有实际查询意义

jion 就是把多个表连接成一个表的手段

多表查询分为 内连接和外连接

select empt .ename,dept .dname,empt .job   from empt as e,dept as d   where empt .deptno=dept .deptno;

select e.ename,d.dname,e.job   from empt as e,dept as d    where e.deptno=d.deptno;

AS 关键字可以给表起别名 as 可以省略

内连接 【inner】join...on          inner可省略

【隐式】 select e.ename,d.dname,e.job     from empt as e,dept as d    where e.deptno=d.deptno;

【显式】select e.ename,d.dname,e.job      from empt as e inner join dept d    on e.deptno=d.deptno;

 特点: 查询结果必须是满足条件的

外连接 【outer】join...on             outer可省略

  • 左连接 Left 【outer】join
  • 右连接 right 【outer】join
  • 全外连接 full join(mysql不支持)

左连接 :以左表为主,先查询出左表,然后查询右表,右表中满足条件的显示,不满足条件的显示为null

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

右连接:右表为主,先查出右表,在查询左表,左表中满足条件的显示,不满足条件的显示为null

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

总结:

1、如果sql用的是Left join 

  •  on后面条件对left 表没作用,只是对right 表起过滤作用
  • where 语句可以对生成临时表后起到过滤,相当于过滤了left表

2、如果sql用的是right join 

  •  on后面条件对right 表没作用,只是对left 表起过滤作用
  • where 语句可以对生成临时表后起到过滤,相当于过滤了right 表

在使用left join时 on 和where区别如下:

1、on条件条件是否为真,是在 生成临时表时使用的条件,不管on的为真,都会返回左边表的数据

2、where条件在生成临时表后,再对临时表进行过滤,如果条件不为真,就会全部过滤。

自然连接 :natural join

自然连接 无需你去给出外键关联等式,它会自动找到这一等式。两张连接表中,名称和类型完全一致的列作为条件。

SELECT * FROM emp NATURAL JOIN dept;
SELECT * FROM emp NATURAL LEFT JOIN dept;
 SELECT * FROM emp NATURAL RIGHT JOIN dept;

总结:

连接查询时,sql查询的核心,按照实际需求来选择对应的类型。

如果选择不当,非但不能提高效率,反而会带来一系列的逻辑错误,甚至性能会下降。

选择依据:

  • 查两张表关联列 相等的数据,用内连接
  • right表时left的子集,用左外连接
  • left表是right的子集,用右外连接
  • right和left 彼此之间的交集,但是互不为子集,使用全外连接

3、子查询

  一个select语句中 包含另一个完整的select语句,子查询 就是 嵌套查询

  1)、单行单列 (用于条件)

   例如 :员工表中 工资高于CLARK的员工都有谁

    分析 :
                1.查询CLARK的工资        select sal from emp where ename="CLARK"

    2.查询高于CLARK的员工  select * from emp where sal > 第一步的结果

    3.结论   select * from emp where sal > (select sal from emp where ename="CLARK")

        2)、单行多列 (用于条件)
                  例如 :查询员工表中 工作 和 工资 与 MARTIN完全相同的员工信息

                  分析 :

                  1.查询MARTIN的工作和工资                 select job,sal from emp where ename="MARTIN"
                 2.查询与MARTIN工作和工资相同的人   select * from emp where (job,sal) in 第一步的结果
                 3.结论             select * from emp where (job,sal) in (select job,sal from emp where ename="MARTIN")

     3).多行单列 (用于条件)

     多行子查询 返回多行数据

在where 使用多行子查询时 要用 all any in

 例如 :查找工资高于30号部门所有人的 员工

  分析 :
                1.查找30号部门所有人的工资                         select sal from emp where deptno=30;
                2.查找高于30号部门所有人工资的员工信息    select * from emp where sal > all 第一步的结果
                3.结论
                    SELECT * FROM emp WHERE sal > ALL (SELECT sal FROM emp WHERE deptno=30);

                   SELECT * FROM emp WHERE sal > ANY (SELECT sal FROM emp WHERE deptno=30);

                /*练习 部门编号为20的员工工资 并且 大于部门编号为30的所有人工资的 员工列表*/
                SELECT * FROM emp WHERE deptno=20 AND sal> ALL(SELECT sal FROM emp WHERE deptno=30)
        4).多行多列 (表)
            例如 :查询员工编号为7788的员工 姓名 工资 部门名称 部门地址
            分析 :涉及到 emp dept两张表
                1.查询 姓名 和 工资
                    select ename,sal from emp where empno=7788
                2.查询 部门名称 和 部门地址
                    select e.ename,e.sal,d.dname,d.loc 
                    from emp e,dept d 
                    where e.deptno = d.deptno and e.empno=7788
                改版:
                    select e.ename,e.sal,d.dname,d.loc 
                    from emp e,(select dname,loc,deptno from dept) d
                    where e.deptno = d.deptno and e.empno=7788

                /*练习 求7369员工 姓名 经理姓名 经理编号 自己连接自己*/
                    SELECT e1.ename,e2.ename,e2.empno 
                    FROM emp e1,(SELECT empno,ename FROM emp) e2 
                    WHERE e1.mgr = e2.empno AND e1.empno = 7369

你可能感兴趣的:(数据库)