MySQL之left join深入理解

本文深入探讨了MySQL中的left join操作,解析了left join的底层执行原理,通过实例展示了如何正确使用left join来满足特定查询需求,如找到每个班级的女生数量和一班的总人数。同时,文章总结了不同where条件对left join结果的影响,帮助读者理解left join与where子句的结合使用以及其与inner join的区别。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.left join 底层执行原理

SELECT * FROM LT LEFT JOIN RT ON P1(LT,RT)) WHERE P2(LT,RT)
  • 其中P1是on过滤条件,缺失则认为是TRUE,P2是where过滤条件,缺失也认为是TRUE,该语句的执行逻辑
FOR each row lt in LT {// 遍历左表的每一行
  BOOL b = FALSE;
  FOR each row rt in RT such that P1(lt, rt) {// 遍历右表每一行,找到满足on条件的行
    IF P2(lt, rt) {//满足 where 过滤条件
      t:=lt||rt;//合并行,输出该行
    }
    b=TRUE;// lt在RT中有对应的行
  }
  IF (!b) { // 遍历完RT,发现lt在RT中没有有对应的行,则尝试用null补一行
    IF P2(lt,NULL) {// 补上null后满足 where 过滤条件
      t:=lt||NULL; // 输出lt和null补上的行
    }         
  }
}

在这里插入图片描述

2. 例子:

在这里插入图片描述

  • 那么现在有两个需求:
    • 找出每个班级的名称及其对应的女同学数量
    • 找出一班的同学总数
  • 对于需求1,大多数人不假思索就能想出如下两种sql写法
    • 正确的:
SELECT c.name, count(s.name) as num 
    FROM classes c left join students s 
    on s.class_id = c.id 
    and s.gender = 'F'
    group by c.name
	-- 错误的
SELECT c.name, count(s.name) as num 
    FROM classes c left join students s 
    on s.class_id = c.id 
    where s.gender = 'F'
    group by c.name

3.总结

  • A left B join on A.id =B.id and A.name=’ ’ and B.name=’ ’ 等条件:不管怎样都会保留左表的所有列。 只保留B表中符合关联条件的。
  • A left B join on A.id =B.id and A.name=’ ’ and B.name=’ ’ where A.age=‘xxx’ 等价于在A表中先where 后再关联left join,因为left join 后无论如何都会保留A表中全部的内容,再使用where 对A表过滤 相当于提前过滤 再关联 结果一样。
(select * from A where A.age='xxx') A left B join  on A.id =B.id  and A.name=' '  and B.name=' '

  • A left B join on A.id =B.id and A.name='TTTT ’ and B.name='XXXX ’ where B.age=‘xxx’ 等价于 A join B 因为A left join B 将B中没有join上的就为空 此时你对B进行过滤 相等于把B为空的都去掉 就只剩下 A和B都能join上的。 所以相当于 inner join
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值