SQL中的连接(2)——SQL读书笔记

2018-06-17 23:04:25来源:未知 阅读 ()

新老客户大回馈,云服务器低至5折

 

《SQL学习指南》中的第10章
  
 1.4 外连接
      在多表连接中,存在连接条件可能无法表中所有的行匹配的问题,例如当account表与customer表进行连接时,会存在account表中cust_id列值无法匹配customer表中的cust_id列值,内连接在无法匹配成功时,是不会将这条匹配失败的结果放入返回的结果集中,假如我们需要强调某个表,也就是某个表的所有行必须返回,这个表的行数决定了返回结果集的行数。
    
    1)左外连接
          关键词:left outer join & left join ,left指出了连接了左边的表决定结果集的行数,而右边只负责提供与之匹配的列值。
     例子1.
        1)查询所有的商业客户账户 ——这是内连接
     
      SELECT a.account_id ,b.cust_id,b.`name`
 FROM  account a INNER JOIN business b
 ON a.cust_id = b.cust_id;
 
     结果如图所示:
        

         2)查询所有的客户,但同时如果是商业客户,返回其客户名称。

         
         SELECT a.account_id ,a.cust_id,b.`name`
FROM  account a LEFT OUTER JOIN business b
ON a.cust_id = b.cust_id;
         
          结果如图所示:
          

            3)查询所有的客户,但同时如果是私人客户,返回其客户名称。

             
 SELECT a.account_id ,a.cust_id,
 CONCAT(i.fname,' ',i.lname) AS gustname
 FROM  account a INNER JOIN individual i
 ON a.cust_id = i.cust_id;
    
     结果如图所示:
             

     2)右外连接

          关键词:right outer join & rigth join ,同理right指出了连接了右的表决定结果集的行数,而左边只负责提供与之匹配的列值。
          1)
          SELECT c.cust_id , b.`name`
 FROM customer c
 RIGHT JOIN business b
          ON c.cust_id = b.cust_id;
          结果如下图所示
          

      3)多表外连接

      
          1)获取所有的账户列表,其中包含个人客户的姓名以及商业客户的企业名称
        
         SELECT a.account_id, 
CONCAT(i.fname,' ',i.lname) AS person_name,
b.`name` as business_name
FROM account a
LEFT JOIN individual i
ON a.cust_id = i.cust_id
LEFT JOIN business b
ON a.cust_id = b.cust_id ;
         
         结果如下图所示
          

               SELECT COUNT(*) FROM account a;

          结果如下
          

              上面多表进行外连接,以account为主表,去匹配individual表中用户,若匹配不成功,显示为null;再去匹配business表中用户,同理匹配不成功,显示为null.同时说明了外连接中,存在以哪个表为主表,所以主表的顺序是不可变,解决上一次笔记中的遗留问题:连接与表的顺序无关,但是外连接要注意主表所在的位置。

          
       通过子查询的方式实现上面的三个表同时进行的自连接:
         
SELECT indi.id, person_name,bussiness_name
FROM (
    SELECT a.account_id AS id, CONCAT(i.fname,' ',i.lname) as person_name
    FROM account a
    LEFT JOIN individual i
  ON a.cust_id = i.cust_id
)  AS indi
INNER JOIN (
    SELECT a.account_id AS id, b.`name` AS bussiness_name
    FROM  account a
    LEFT JOIN business b
    ON a.cust_id = b.cust_id
) AS busi
ON indi.id =  busi.id;
结果如下图所示
         
      4)自外连接
      
          1)前面通过内连接实现的一个问题:获取雇员及其主管的信息
         SELECT e.emp_id,CONCAT(e.fname,' ',e.lname) AS emp_name,
em.emp_id AS su_emp_id,CONCAT(em.fname,' ', em.lname) AS superior_name
FROM employee e
INNER JOIN employee em
ON e.superior_emp_id = em.emp_id;
 
结果如下图所示:

 

上面的结果由于是内连接的原因,雇员信息会缺失一条,因为总经理是最高级别职员,没有上级,所以匹配不成功,没有在结果集中显示。下面通过左连接的方式,可以解决这个问题。
    
     SELECT e.emp_id,CONCAT(e.fname,' ',e.lname) AS emp_name,
em.emp_id AS su_emp_id,CONCAT(em.fname,' ', em.lname) AS superior_name
FROM employee e
LEFT JOIN employee em
ON e.superior_emp_id = em.emp_id;
 
结果如下图所示:

 

       将上面的左连接更改成右连接,这时候就是获取每个主管的下属职员
    
    SELECT e.emp_id,CONCAT(e.fname,' ',e.lname) AS emp_name,
em.emp_id AS su_emp_id,CONCAT(em.fname,' ', em.lname) AS superior_name
FROM employee e
RIGHT JOIN employee em
ON e.superior_emp_id = em.emp_id;
结果如下图所示:

当某个主管下面存在n个职员时,这样就会在该主管对应的数据增加n-1条数据,这也就是18个雇员,为什么查出的结果集中有28条数据的。

          
    
 
     
    
    
 
 
 
 
 
 
 
 
 
 
 

标签:

版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有

上一篇:关系型数据库表与表之间的三种关系

下一篇:python--同一mysql数据库下批量迁移数据