LEFT OUTER JOIN添加ON条件后COUNT结果不同的原因咨询
左连接后计数差异的原因解析
你混淆了「左连接保留左表所有行」和「左连接结果总行数等于左表行数」这两个概念,这是核心误解点,下面拆解两个查询的逻辑:
第一个查询的计数逻辑
select count(*) from products p left outer join order_details_v od on p.product_id = od.order_item_product_id
左连接的规则是:左表(products)的每一行,会与右表(order_details_v)中所有匹配product_id的行生成结果行;如果左表某行在右表中没有匹配项,会单独生成一行(右表字段全为null)。
你得到的12332是所有结果行的总数,这说明你的products表中存在大量对应多条订单详情的产品——比如一个产品对应10条订单记录,就会在结果中生成10行,最终总计数远大于products表本身的行数。
第二个查询的计数逻辑
select count(*) from products p left outer join order_details_v od on p.product_id = od.order_item_product_id and to_char(od.order_date::timestamp, 'yyyy-MM') = '2014-01'
你在ON子句中新增了日期条件,这会提前过滤右表中参与连接的行:只有2014年1月的订单详情才会和左表产品匹配。此时结果行的生成规则变为:
- 对于左表的每个产品,仅与右表中符合日期条件的订单详情行生成匹配结果;
- 没有符合日期条件订单的产品,依然保留1行结果(右表字段为
null)。
原本一个产品可能对应10条订单记录(贡献10行结果),现在最多贡献N行(N是该产品2014-01的订单数,可能是0、1或少量),因此总计数会大幅降低,最终得到1224。
验证建议
如果你想确认products表本身的行数,可以执行:
select count(*) from products;
这个数值应该等于第二个查询的1224(因为左连接一定会保留左表所有行,结果行数不会少于左表行数)。
内容的提问来源于stack exchange,提问作者DumbCoder
相关产品推荐
相关产品推荐

