mybatis的left join多条件操作

  • Post author:
  • Post category:其他




一. 背景

小熙在修改一个bug的时候,想直接在左连接后面加上条件,但是深思后发现在不同情况下却有数据不一致的问题。



二. 过程

  1. 小熙随机创建了 两张表一张学生表和另一张班级表

    (1)

    SELECT * FROM student;


    学生表

    (2)

    SELECT * FROM classes;


    班级表

  2. 以学生表为左表对班级表进行 left join:

    SELECT * FROM student s LEFT JOIN classes c ON  s.classes_id = c.classes_id;
    

    左连接

    (1) 当在左连接后面,继续设置班级为C001条件的查询结果为:

     SELECT * FROM student s LEFT JOIN classes c ON    s.classes_id = c.classes_id AND c.classes_id = 'C001'
    

    where后面的

    (2) 当你将班级限制条件加在 where 后面的时候结果为:

     SELECT * FROM student s LEFT JOIN classes c ON  s.classes_id = c.classes_id  WHERE c.classes_id = 'C001'; 			
    

    where后面

    (3) 当然你也可以在 on 后面继续写限制条件,但是需要在 where 后面加上 is not null 语句:

     SELECT * FROM student s LEFT JOIN classes c ON  s.classes_id = c.classes_id AND c.classes_id = 'C001' WHERE c.classes_id IS NOT NULL;		
    

    不为空

    (4) 在 on 后面加上限制主表的条件:

     SELECT * FROM student s LEFT JOIN classes c ON  s.classes_id = c.classes_id and s.student_id = 's001'
    

    主表限制



三. 结果:

  1. 定义解释:

    left jion 在学习的时候就已经定义的很清楚了,是以左表为主,将从表的数据按条件填充上去进行连接,没有符合的则以 null 的形式展示。所以不会减少数据展示。

    (1) 关于过程中的第四条,有限制了主表的条件,但是展示数据却是非期望的:

    在Oracle官网有着这样的一段说明:

       left outer join
       The result of a left outer join for table A and B contains all records of the left table A,
       even if the join condition does not match a record in the right table B. For example, if
       you perform a left outer join of employees (left) to departments (right), and if some
       employees are not in a department, then the query returns rows from employees
       with no matches in departments.
    

    (2) 在《Database System Concepts》这本书中找到的相关说明:

           The right outer join is symmetric with the left outer join: It pads tuples
       from the right relation that did not match any from the left relation with nulls and
       adds them to the result of the natural join. In Figure 6.18, tuple (58583, null, null,
       null, null, Califieri, History, 62000), is such a tuple. Thus, all information from the
       right relation is present in the result of the right outer join.
    

    (3) 总结:

       left join的结果集一定会包含左边表的所有记录。同理,right join一定会包含右边表的所有记录。
       	
       所以,使用时应该只在on子句中包含关联条件,单独对某个表的限制应该放到where子句中。
       	
       和小熙说的定义的原理是一样的。
    
  2. 结论:

    如上述过程所展示,如果要限制主表中的数据请在 where 后面限制, 如果要限制从表中的数据可以在 on 后面加以限制

    ,但是如果你需要将限制的从表数据,所关联的主表数据也不显示的话,你需要在 where 后面

    加上从表对应数据不为 null 的限制(如例三),这样的好处在数据量大和多运算时会体现出较好的效率(减少查询和后续

    运算的消耗)



版权声明:本文为weixin_41133233原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。