mysql 多表查询

1、多表查询的种类?


  在实际查询中,我们会更多的使用多表查询,那么多表查询的种类有哪几种呢?如下:

  (1)合并结果集

  (2)连接查询

     ➤内连接

     外连接

        左外连接

        右外连接

        ◇全外连接(MySQL不支持,可通过union左外和右外实现)

     自然连接

  (3)子查询


2、合并结果集


  作用:合并结果集就是把两个select语句的查询结果纵向合并到一起。

  要求:被合并的两个结果:列数、列类型必须相同。

  合并结果集有两种方式:

    UNION:去除重复记录,例:SELECT * FROM t1 UNION SELECT * FROM t2;

    UNION ALL:不去除重复记录,例:SELECT * FROM t1 UNION ALL SELECT * FROM t2。



3、连接查询


  连接查询就是求出多个表的乘积,例如t1连接t2,那么查询出的结果就是t1*t2。



  连接查询会产生笛卡尔积,比如emp表一共14行记录,dept 4行记录,那么连接后查询出的结果是56行记录。但是多表查询产生这样的结果并不是我们想要的,那么去除重复的记录就是通过条件过滤,通常要查询的多个表之间都存在关联关系,那么就通过关联关系去除笛卡尔积。一般我们都使用主外键关系做为条件来去除笛卡尔积。




  例如:

[sql]  view plain  copy
  1. <span style="font-size:18px;">SELECT emp.ename,emp.sal,emp.comm,dept.dname   
  2. FROM emp,dept   
  3. WHERE emp.deptno=dept.deptno;/*(deptno是dept的主键,是emp的外键)*/  
  4. </span>  


  (1)内连接


    上面的连接语句就是内连接,但它不是SQL标准中的查询方式,就是前面《结构化查询语言》中所说的方言。SQL标准的内连接为:
[sql]  view plain  copy
  1. <span style="font-size:18px;">SELECT *   
  2. FROM emp e   
  3. INNER JOIN dept d   
  4. ON e.deptno=d.deptno;</span>  

    内连接的特点:查询结果必须满足查询所使用的条件。


  (2)外连接


    分为左外连接和右外连接。特点:查询出的结果存在不满足条件的可能,如null。


    ● 左外连接

      左表数据无论是否满足关联条件都会出现!右表显示匹配数据!如果左表不匹配关联条件,右表补null。

[sql]  view plain  copy
  1. <span style="font-size:18px;">SELECT * FROM emp e   
  2. LEFT OUTER JOIN dept d   
  3. ON e.deptno=d.deptno;</span>  

      左连接是先查询出左表(即以左表为主),然后查询右表,右表中满足条件的显示出来,不满足条件的显示NULL。


    ● 右外连接

      右连接就是先把右表中所有记录都查询出来,然后左表满足条件的显示,不满足显示NULL。

[sql]  view plain  copy
  1. <span style="font-size:18px;">SELECT * FROM emp e   
  2. RIGHT OUTER JOIN dept d   
  3. ON e.deptno=d.deptno;</span>  



    ● 全外连接

      mysql是不支持全外连接的,但是我们通过这样来实现:

[sql]  view plain  copy
  1. /* 左右不满足条件的也都显示出来,都补null */  
  2. SELECT * FROM emp e LEFT OUTER JOIN dept d ON e.deptno=d.deptno  
  3. UNION  
  4. SELECT * FROM emp e RIGHT OUTER JOIN dept d ON e.deptno=d.deptno  


    连接查询心得:

      连接不限与两张表,连接查询也可以是三张、四张,甚至N张表的连接查询。通常连接查询不可能需要整个笛卡尔积,而只是需要其中一部分,那么这时就需要使用条件来去除不需要的记录。这个条件大多数情况下都是使用主外键关系去除。

      两张表的连接查询一定有一个主外键关系,三张表的连接查询就一定有两个主外键关系,所以在大家不是很熟悉连接查询时,首先要学会去除无用笛卡尔积,那么就是用主外键关系作为条件来处理。如果两张表的查询,那么至少有一个主外键条件,三张表连接至少有两个主外键条件。

  (3)自然连接

    大家也都知道,连接查询会产生无用笛卡尔积,我们通常使用主外键关系等式来去除它。而自然连接无需你去给出主外键等式,它会自动找到这一等式:两张连接的表中名称和类型完成一致的列作为条件,例如emp和dept表都存在deptno列,并且类型一致,所以会被自然连接找到!当然自然连接还有其他的查找条件的方式,但其他方式都可能存在问题!

[sql]  view plain  copy
  1. <span style="font-size:18px;">SELECT * FROM emp NATURAL JOIN dept;  
  2. SELECT * FROM emp NATURAL LEFT JOIN dept;  
  3. SELECT * FROM emp NATURAL RIGHT JOIN dept;</span>  


4、子查询


  子查询就是嵌套查询,即SELECT中包含SELECT,如果一条语句中存在两个,或两个以上SELECT,那么就是子查询语句了。


  子查询出现的位置:


    where后:作为条件的一部分;

    from后:作为被查询的一条表;

  当子查询出现在where后作为条件时,还可以使用如下关键字:any、all。

[sql]  view plain  copy
  1. <span style="font-size:18px;">/*  
  2. 1. 使用all,查询工资大于30部门所有人的员工信息  
  3. */  
  4. SELECT * FROM emp e  
  5. WHERE sal > ALL (SELECT sal FROM emp e WHERE deptno=30)  
  6.   
  7. /*  
  8. 2. 使用any,查询工资小于30部门任意一人的员工信息  
  9. */  
  10. SELECT * FROM emp e  
  11. WHERE sal < ANY (SELECT sal FROM emp e WHERE deptno=30)</span>  

  

  子查询结果集的形式:


    单行单列(用于条件,即where后):

[sql]  view plain  copy
  1. <span style="font-size:18px;">/*  
  2. 单行单列 --> 单个值  
  3. 1. 查询与阿飞同一部门的所有员工  
  4. */  
  5. SELECT * FROM emp e WHERE deptno=(SELECT deptno FROM emp WHERE ename='阿飞')</span>  

    单行多列(用于条件):

[sql]  view plain  copy
  1. <span style="font-size:18px;">/*  
  2. 单行多列 --> 对象  
  3. 3. 查询工资和部门与小张都相同的员工信息  
  4. */  
  5. SELECT * FROM emp e WHERE (sal,deptno)=(SELECT sal, deptno FROM emp WHERE ename='小张')</span>  

    多行单列(用于条件):

[sql]  view plain  copy
  1. <span style="font-size:18px;">/*  
  2. 多行单列 --> 数组  
  3. 2. 查询与小张或阿飞同一部门的所有员工  
  4. */  
  5. SELECT * FROM emp e WHERE deptno IN (SELECT deptno FROM emp WHERE ename IN ('小张''阿飞'))</span>  

    多行多列(作为表的形式,即from后):

[sql]  view plain  copy
  1. <span style="font-size:18px;">SELECT * FROM emp e INNER JOIN (SELECT * FROM dept WHERE deptno>10) d</span>  

  小结:多表查询包括合并结果集、连接查询和子查询,连接查询中多表操作一定会用到主外键关系去除笛卡尔积;子查询中要注意子查询所在位置,代表了子查询的作用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值