mysql之外连接的用法

       现在假设有两个表,分别为a表和b表,a表与b表外键关联,如果我们想要查询a表和b表中的一些记录,我们就需要通过a表的外键和b表的主键进行连接。
       但是假设如下情况。 b表有主键bno,数据为b1,b2,b3 a表中有外键bno,但是只有关于b1,b2的数据,没有关于b3的数据(这里只考虑bno,其他属性类似bname等可不考虑),如果我们进行等值连接的话,连接后关于b3的数据必然会丢失,假如我们想查询bno值为b3的信息的话,是肯定查询不到的,因为已经丢失了。
       从这里我们也可以看出等值连接的特点。如果主外键匹配,连接成功,数据可以显示。如果主外键不匹配(或者无法匹配,如上面的情况),连接失败,该数据丢失。
       如果我们想要查询出某些等值连接会丢失的数据,应该怎么做呢,这时候就要用外连接了。
      外连接有左外连接、右外连接和全外连接,这里逐一介绍。
先给出创建表的语句和插入数据的语句:
创建表的语句:
CREATE TABLE `csdn`.`b` (
  `bno` CHAR(5) NOT NULL,
  PRIMARY KEY (`bno`));
CREATE TABLE `csdn`.`a` (
  `ano` CHAR(5) NOT NULL,
  `bno` CHAR(5) NULL,
  PRIMARY KEY (`ano`),
  CONSTRAINT `FK_a_b`
    FOREIGN KEY (bno)
    REFERENCES `csdn`.`b` (bno)
    ON DELETE NO ACTION
    ON UPDATE NO ACTION);
这里我的数据库名为csdn,如果不同的话改成自己正在使用的数据库即可。(或者创建一个新数据库更方便点)创建表的顺序应该是先b后a,因为a与b外键关联。
插入数据的语句:
INSERT INTO `csdn`.`b` (`bno`) VALUES ('b1');
INSERT INTO `csdn`.`b` (`bno`) VALUES ('b2');
INSERT INTO `csdn`.`b` (`bno`) VALUES ('b3');
INSERT INTO `csdn`.`a` (`ano`, `bno`) VALUES ('a1', 'b1');
INSERT INTO `csdn`.`a` (`ano`, `bno`) VALUES ('a2', 'b2');
  1.左外连接
     左外连接(LEFT JOIN)是指将左表中的所有数据分别与右表中的每条数据进行连接组合,返回的除内连接外,还包括左表中不符合条件的数据,并在右表的相应列中添加NULL值。
     简单点来说,就是可以等值连接的就等值连接,不能的左表数据保留,右表数据全部用NULL填上。
     那上面的假设就可以这样写出。
   
select  * from b left join a on a.bno=b.bno
where a.bno IS NULL;
2.右外连接
       右外连接(RIGHT JOIN)是指右表中的所有数据分别与左表中的每条数据进行连接组合,返回的结构除内连接数据外,还包括右表中不复合条件的数据,并在左表的相应列中添加NULL。
和左外连接是类似的。只是数据部分和NULL部分左右互换而已。
select * from a right join b on a.bno=b.bno;
但是这里要搞清楚的是到底是哪个表的数据会被丢失,例如上面的例子中,我们知道进行等值连接的话是b表的信息会被丢失,所以b表就不能放在会被赋值NULL的位置,不然的话效果等同等值连接。
select * from b right join a on a.bno=b.bno;
select * from a left join b on a.bno=b.bno;
select * from a,b where b.bno=a.bno;
这三条语句执行后结果只有两行。(这里才知道原来连接时属性的顺序是按照你的输入的表的顺序来的。。)
3.全外连接
全外连接(FULL  JOIN 或 FULL OUTER JOIN) 完整外部连接返回左表和右表中的所有行。当某行在另一个表中没有匹配行时,则另一个表的选择列表列包含空值。如果表之间有匹配行,则整个结果集行包含基表的数据值。  
但是在mysql中,并不支持全外连接。所以这里不再给出查询语句和结果。
总结:如果要确保在连接的过程中数据不会丢失,我们就需要使用外连接,但是我们也需要知道哪个表的信息是将会被丢失的。这里有个简单点的方法,就是左外和右外各写一句。但是表的位置要相同(均为b在前或者均为a在前,如下),这样观察一下两表的不同就知道了。
select * from b left join a on a.bno=b.bno;
select * from b right join a on a.bno=b.bno;
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值