You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

LEFT JOIN返回结果与INNER JOIN一致,存入视图却正常,原因何在?

问题分析与解决方案

嘿,咱们来好好捋捋你遇到的这个SQL问题:你本来想用LEFT JOIN找出A表中在B表里没匹配的行,结果查询结果却和INNER JOIN一模一样,存入视图后反而正常了——这背后其实是LEFT JOIN的逻辑细节没搞对。

为啥原查询会变成INNER JOIN的效果?

说白了,问题出在WHERE子句里的B表字段过滤条件。当你用LEFT JOIN时,A表的所有行都会被保留下来,那些在B表里找不到匹配的A行,对应的B表字段全是NULL。但你加了date(b.trt_date) = '2017-11-18'这个条件,对于B表字段为NULL的那些行来说,date(NULL)还是NULL,而NULL和任何值做比较的结果都是不成立的,WHERE子句直接把这些行给过滤掉了。最后剩下的就只有A和B能匹配上,且B表日期符合条件的行,这不就和INNER JOIN的结果完全一样了嘛!

正确的查询写法应该是这样

要实现“找出A表中与B表无匹配的行,同时如果有匹配的话只关联B表中日期符合条件的行”,你得把B表的过滤条件放到LEFT JOIN的ON子句里,而不是WHERE里:

SELECT * 
FROM A 
LEFT JOIN B 
  ON A.A1 = B.B1 
  AND DATE(b.trt_date) = '2017-11-18' -- 把B表的条件移到ON里
WHERE a.tcs_type = 'SALES' 
ORDER BY a.tcs_no ASC;

这样一来,LEFT JOIN会先筛选出B表里符合日期条件的行,再和A表做关联。A表中找不到匹配的行依然会被保留,对应的B表字段全是NULL,这才是你想要的结果。

那为啥存入视图后就正常了?

这十有八九是你创建视图时的SQL语句,和你直接执行的查询不一样!比如你可能在写视图的SQL时,不小心把B表的日期条件移到了ON子句里,或者调整了条件的位置。你可以去Navicat/SQLyog里查看一下视图的定义语句,和你之前直接跑的查询对比一下,肯定能发现差异。当然,也不排除工具缓存的小概率情况,但最可能的还是视图的SQL逻辑更符合LEFT JOIN的正确用法。

内容的提问来源于stack exchange,提问作者padjee

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 07:04:58