使用 LEFT JOIN 时,将条件写在 ON 子句和 WHERE 子句的区别

1. 条件写在 ON 子句中

当条件写在 ON 子句中时,条件会在进行连接操作时立即应用。这意味着只要左表中的行存在,不论右表中的行是否满足条件,左表的行都会包含在结果集中。如果右表中的行不满足条件,结果集中会显示右表的列为空。

示例

SELECT *
FROM t_user u
LEFT JOIN t_user_role ur ON u.id = ur.user_id AND ur.is_delete = 0;

在这个例子中,即使 ur.is_delete 不为 0,左表 t_user 中的行也会包含在结果集中,只是对应的 t_user_role 表的列会为空。

2. 条件写在 WHERE 子句中

当条件写在 WHERE 子句中时,连接操作首先完成,然后对整个结果集应用 WHERE 子句中的条件。这会导致在 LEFT JOIN 的情况下,如果右表中没有满足条件的行,对应的左表中的行也会被过滤掉。这与 LEFT JOIN 保留左表所有行的初衷相悖。

示例

SELECT *
FROM t_user u
LEFT JOIN t_user_role ur ON u.id = ur.user_id
WHERE ur.is_delete = 0;

在这个例子中,只有 ur.is_delete 为 0 的行会包含在结果集中。如果右表 t_user_role 中的行不满足条件 ur.is_delete = 0,那么这些行将被过滤掉,并且相应的左表 t_user 中的行也会从结果集中移除。

对比总结

ON 子句:保留左表中的所有行,即使右表中没有匹配行,结果集中对应的右表列会显示为 NULL。
WHERE 子句:过滤整个结果集,不保留左表中没有匹配右表条件的行。

实例对比

假设我们有两张表:

t_user:
+----+-------+
| id | name  |
+----+-------+
| 1  | Alice |
| 2  | Bob   |
| 3  | Carol |
+----+-------+

t_user_role:
+----+---------+----------+
| id | user_id | is_delete|
+----+---------+----------+
| 1  | 1       | 0        |
| 2  | 2       | 1        |
| 3  | 3       | 0        |
+----+---------+----------+

条件在 ON 子句中

SELECT u.id, u.name, ur.is_delete
FROM t_user u
LEFT JOIN t_user_role ur ON u.id = ur.user_id AND ur.is_delete = 0;

结果:

+----+-------+----------+
| id | name  | is_delete|
+----+-------+----------+
| 1  | Alice | 0        |
| 2  | Bob   | NULL     |
| 3  | Carol | 0        |
+----+-------+----------+

条件在 WHERE 子句中

SELECT u.id, u.name, ur.is_delete
FROM t_user u
LEFT JOIN t_user_role ur ON u.id = ur.user_id
WHERE ur.is_delete = 0;

结果:

+----+-------+----------+
| id | name  | is_delete|
+----+-------+----------+
| 1  | Alice | 0        |
| 3  | Carol | 0        |
+----+-------+----------+

如上所示,当条件写在 ON 子句中时,t_user 表中的所有行都会保留,而条件写在 WHERE 子句中时,t_user 表中没有满足条件的行会被过滤掉。

posted @ 2024-07-02 17:02  天不高地不阔  阅读(120)  评论(0)    收藏  举报