LEFT OUTER JOIN调换表顺序后count(*)结果相同,无法理解原因
问题原因解答
你对LEFT OUTER JOIN的基础认知是正确的,但漏了一个核心前提:只有当左表的每条记录在右表中最多匹配到1条记录时,JOIN后的总条数才等于左表的条数,如果是一对多的匹配关系,总条数会远大于左表本身的行数。
场景差异说明
你之前举的小例子默认是一对一的匹配关系,1条左表记录最多匹配1条右表记录,所以总条数始终等于左表的15条。但在dvdrental数据库的业务场景下,customer表和payment表是典型的一对多关系:1个客户可以产生多笔支付记录,所以1条customer表的记录会匹配到多条payment表的记录。
你执行的SQL结果解释
你调换顺序后的SQL(忽略你手敲的cusotmer拼写错误,实际执行应该是正确的customer_id):
select count(*) from customer left outer join payment on payment.customer_id=customer.customer_id;
返回14596的原因非常简单:
payment表的所有14596条记录都有对应的有效customer_id(该字段是外键非空约束,所有支付记录必然关联了已存在的客户)- 每笔支付记录都会和对应的客户记录匹配成功,最终JOIN后的结果总行数就等于
payment表的总条数14596 - 如果存在没有产生过任何支付记录的客户,总结果会是14596加上这类客户的数量
如何得到你预期的599结果
如果你想要统计左表customer的去重条数,不要用count(*),改为统计左表主键的去重值即可:
select count(DISTINCT customer.customer_id) from customer left outer join payment on payment.customer_id=customer.customer_id;
这个语句的执行结果就是你预期的599。
内容的提问来源于stack exchange,提问作者Tapan Das
相关产品推荐
相关产品推荐

