您的位置:首页 > 数据库 > MySQL

mysql → 多表查询

2016-01-08 22:47 691 查看

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行记录。但是多表查询产生这样的结果并不是我们想要的,那么去除重复的记录就是通过条件过滤,通常要查询的多个表之间都存在关联关系,那么就通过关联关系去除笛卡尔积。一般我们都使用主外键关系做为条件来去除笛卡尔积。



  例如:

<span style="font-size:18px;">SELECT emp.ename,emp.sal,emp.comm,dept.dname
FROM emp,dept
WHERE emp.deptno=dept.deptno;/*(deptno是dept的主键,是emp的外键)*/
</span>


  (1)内连接

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

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

  (2)外连接

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

    ● 左外连接

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

<span style="font-size:18px;">SELECT * FROM emp e
LEFT OUTER JOIN dept d
ON e.deptno=d.deptno;</span>


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

    ● 右外连接

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

<span style="font-size:18px;">SELECT * FROM emp e
RIGHT OUTER JOIN dept d
ON e.deptno=d.deptno;</span>




    ● 全外连接

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

/* 左右不满足条件的也都显示出来,都补null */
SELECT * FROM emp e LEFT OUTER JOIN dept d ON e.deptno=d.deptno
UNION
SELECT * FROM emp e RIGHT OUTER JOIN dept d ON e.deptno=d.deptno

    连接查询心得:

      连接不限与两张表,连接查询也可以是三张、四张,甚至N张表的连接查询。通常连接查询不可能需要整个笛卡尔积,而只是需要其中一部分,那么这时就需要使用条件来去除不需要的记录。这个条件大多数情况下都是使用主外键关系去除。
      两张表的连接查询一定有一个主外键关系,三张表的连接查询就一定有两个主外键关系,所以在大家不是很熟悉连接查询时,首先要学会去除无用笛卡尔积,那么就是用主外键关系作为条件来处理。如果两张表的查询,那么至少有一个主外键条件,三张表连接至少有两个主外键条件。

  (3)自然连接

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

<span style="font-size:18px;">SELECT * FROM emp NATURAL JOIN dept;
SELECT * FROM emp NATURAL LEFT JOIN dept;
SELECT * FROM emp NATURAL RIGHT JOIN dept;</span>


4、子查询

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

  子查询出现的位置:

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

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

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

<span style="font-size:18px;">/*
1. 使用all,查询工资大于30部门所有人的员工信息
*/
SELECT * FROM emp e
WHERE sal > ALL (SELECT sal FROM emp e WHERE deptno=30)

/*
2. 使用any,查询工资小于30部门任意一人的员工信息
*/
SELECT * FROM emp e
WHERE sal < ANY (SELECT sal FROM emp e WHERE deptno=30)</span>


  

  子查询结果集的形式:

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

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


    单行多列(用于条件):

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


    多行单列(用于条件):

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


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

<span style="font-size:18px;">SELECT * FROM emp e INNER JOIN (SELECT * FROM dept WHERE deptno>10) d</span>

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

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: