之前我写过一篇文章叫做,《SQL 中 关于Left Join 转为 Inner Join 的问题》。文章中给出的一个结论是:左关联的查询语句中,只要有 where 的过滤条件,那么该语句将被转为内关联。
继续上一篇的内容,在这篇文章中我来说说在日常开发中的一个实际应用。说来简单,但是不知道的人也经常颇受困扰。
应用:对 Left Join 之后的数据进行过滤,即对左关联之后的数据进行过滤
还是用前一篇文章的例子来说明,建表语句和造数语句均可在前一篇找到,在此不做累赘。
需求说明:
进入界面的时候,需要根据需求查询出所有数据。同时在查询的数据之上有可输入的过滤条件,可以对查询出来的结果进行筛选过滤。即,在进入界面时需要查询出 class 中 student 的 sex = 1 的数据,同时界面上有个可输入的过滤条件 classID 。大体结构如下图:
进入界面时的查询语句如下:
SELECT *
FROM T_CLASS A
LEFT JOIN T_STUDENT B
ON A.CLASS_ID = B.CLASS_ID
AND B.SEX = 1
ORDER BY A.CLASS_ID;
查询结果如下:
此时的问题是:如何把 classID 过滤条件加入到这个查询语句中?
经常有人是这么加 classID 的条件的:
SELECT *
FROM T_CLASS A
LEFT JOIN T_STUDENT B
ON A.CLASS_ID = B.CLASS_ID
AND B.SEX = 1
AND A.CLASS_ID = 1
ORDER BY A.CLASS_ID;
得到的查询结果如下图:
数据中仍然带着 student 为空的 class 。原因是,这样的写法,SQL 语句仍然是左关联,空数据无法被过滤。
分析一下需求,添加过滤条件之后,查询结果应该已不是左关联,而是内关联。
此时我们有两种做法
第一种,直接将左关联改为内关联,即将 Left Join 改为 Inner Join
SELECT *
FROM T_CLASS A
INNER JOIN T_STUDENT B
ON A.CLASS_ID = B.CLASS_ID
AND B.SEX = 1
AND A.CLASS_ID = 1
ORDER BY A.CLASS_ID;
查询结果如下:
但是,很多情况下我们不会因为功能中需要有过滤条件而重新写一个查询语句。更多的情况,还是在原有的查询语句中增加过滤条件。此时需要第二种做法。
第二种,用 where 进行过滤,查询语句如下:
SELECT *
FROM T_CLASS A
INNER JOIN T_STUDENT B
ON A.CLASS_ID = B.CLASS_ID
AND B.SEX = 1
WHERE A.CLASS_ID = 1
ORDER BY A.CLASS_ID;
查询结果如下:
就像我在之前文章说的,左关联的查询语句中,只要有 where 的过滤条件,那么该语句将被转为内关联。此时这个用法派上用场了。