跳到主要内容
JackSparrow414
返回

关于MySQL多表关联时过滤条件的位置

本文导航

展开本文导航

正文

简单的一个Demo说明下问题

LEFT JOIN 示例的表 A,包含 id、name 与 status 字段

LEFT JOIN 示例的表 B,包含 microservice_id 与 project_id 关联字段

表A和表B关联查询,以project_id=4为过滤条件,查询结果返回表A中的ID,name,表B中的project_id,如果表B中没有和表A匹配的记录则a.project_id返回null,于是第一次我就写出了这样的SQL

SELECT
	t.id,t.name,a.project_id
FROM
	micrisevice AS t
	LEFT JOIN project_mirservie AS a ON a.micrservice_id = t.id
	WHERE t.STATUS = 0 AND a.project_id = 4 OR a.id is NULL

问题直接出现了,left join 应该无论如何要返回左表(这里指表A)的所有记录,但是结果却不是这样的,如下

WHERE 过滤后的 LEFT JOIN 结果缺少 id 为 2 的记录

结果为ID 为2的那条数据不见了,怎么回事,一开始我以为是AND 和 OR中的条件没有加括号导致的,加了括号之后还是一样的结果,于是我就把t.STATUS=0 后面的条件删除,看看这次执行的结果是什么样的,如图

未按 project_id 过滤的 LEFT JOIN 结果,包含一对多关联记录

可以看到这里是left join之后的结果,看到这我明白了,刚才的条件是作用在这张临时表上了,所以导致查询条件where a.project_id= 4直接把project_id为3,5,3的过滤掉了,这和我一开始的期望是不符合的,所以应该是把条件放到 left join里去,这样才会得到我想要的临时表,如下

SELECT
	t.id,
	t.NAME,
	a.project_id
FROM
	micrisevice AS t
	LEFT JOIN project_mirservie AS a ON a.micrservice_id = t.id
	AND a.project_id = 4
	OR a.id IS NULL
WHERE
	t.STATUS = 0

这样再用where条件对临时表过滤才是期望的结果

将 project_id 条件放入 JOIN 后保留表 A 全部记录的查询结果


分享本文:

上一篇
springboot的异步调用@Async和事务@Transactional注解的注意事项
下一篇
关于项目中DNS中的问题

评论

欢迎提问、纠错和分享经验。发表评论需要登录 GitHub;中英文版本共享评论。

评论仅在正式网站开放。