前言
子表的字段也是可以加where条件的,只不过看加在哪里。
where
如果加在where里面,则会过滤数据。就像主表的字段,也是用来过滤数据。
on
如果加在on里面,则不会过滤数据。如果没有匹配到,子表的字段为null。
总结
加在where,就是加在主表,作用就是过滤主表数据。应用场景是搜索,比如查询列表的时候,会根据条件过滤。
加在on,其实就是加在子表,作用不是过滤主表数据,而是为了过滤子表——但是如果没有匹配上子表记录,也不会过滤主表,而是字段的值为null。应用场景是查询列表,比如子表的字段如果匹配就显示,没有匹配就不显示呗。
chatgpt
问题
<!-- 左连接wk_shop -->
LEFT JOIN `wk_shop` t4
ON t4.steward_shop_id = a.steward_shop_id and t4.type='ACTUAL_SITE'。
左连接的时候,可以and t4.type='ACTUAL_SITE'吗
回答
可以的!在 SQL 中,LEFT JOIN 的 ON 条件中可以包含多个条件,通过 AND 来连接是完全有效的。你的这段 SQL 语句:
LEFT JOIN
`wk_shop` t4
ON
t4.steward_shop_id = a.steward_shop_id AND t4.type = 'ACTUAL_SITE'
表示在执行 LEFT JOIN 时,t4 表中的记录需要满足以下两个条件:
t4.steward_shop_id = a.steward_shop_idt4.type = 'ACTUAL_SITE'
这两个条件会一同决定哪些记录可以被连接到主表中。如果满足条件的记录不存在,那么连接的结果中会用 NULL 来表示 t4 表中对应的字段。
注意点
- 执行顺序
LEFT JOIN的条件优先于WHERE,即ON中的条件会在进行表连接时生效,而WHERE会在连接后的结果集中再进行筛选。 - 性能问题
如果wk_shop表数据量大且未对type和steward_shop_id建立索引,查询性能可能会受到影响。可以考虑为这两个字段添加索引以提升查询效率。 - 逻辑清晰度
这种写法逻辑清晰,通常在LEFT JOIN中直接加上AND条件是很常见的实践,不会影响语义或功能。
你可以直接使用这种写法,它在语法上是正确的,并且能够满足大多数需求。
问题
on里面的条件t4.type = 'ACTUAL_SITE'如果不满足,那么就是null,并不会过滤数据。而主表的where里面的子表条件t4.type = 'ACTUAL_SITE'如果不满足,则会过滤数据。对吗?
回答
完全正确!
ON 和 WHERE 的区别
ON条件
LEFT JOIN的ON条件是用于指定两个表之间如何进行匹配。即使ON条件中的部分条件(如t4.type = 'ACTUAL_SITE')不满足,主表的数据仍然会保留,LEFT JOIN结果中对应的子表字段会显示为NULL。WHERE条件
WHERE条件是用来过滤最终的查询结果。如果在WHERE中加了对子表的条件(如t4.type = 'ACTUAL_SITE'),会导致不满足条件的记录被过滤掉,这样主表中本应保留的记录也会丢失。
举例说明
假设有两张表:
表 main_table(主表)
| id | name | steward_shop_id |
|---|---|---|
| 1 | Alice | 101 |
| 2 | Bob | 102 |
表 wk_shop(子表)
| steward_shop_id | type | shop_name |
|---|---|---|
| 101 | ACTUAL_SITE | Shop A |
| 102 | ONLINE_SITE | Shop B |
SQL 1:ON 中包含 t4.type = 'ACTUAL_SITE'
SELECT a.*, t4.shop_name
FROM main_table a
LEFT JOIN wk_shop t4
ON a.steward_shop_id = t4.steward_shop_id AND t4.type = 'ACTUAL_SITE';
结果:
| id | name | steward_shop_id | shop_name |
|---|---|---|---|
| 1 | Alice | 101 | Shop A |
| 2 | Bob | 102 | NULL |
解释:
即使 Bob 的 steward_shop_id = 102 在子表中没有满足 type = 'ACTUAL_SITE' 的条件,主表的记录依然会保留,只是子表相关字段会显示为 NULL。
SQL 2:在 WHERE 中加上 t4.type = 'ACTUAL_SITE'
SELECT a.*, t4.shop_name
FROM main_table a
LEFT JOIN wk_shop t4
ON a.steward_shop_id = t4.steward_shop_id
WHERE t4.type = 'ACTUAL_SITE';
结果:
| id | name | steward_shop_id | shop_name |
|---|---|---|---|
| 1 | Alice | 101 | Shop A |
解释:
WHERE 条件会过滤掉那些 t4.type != 'ACTUAL_SITE' 或 t4.type IS NULL 的记录,因此 Bob 的记录被完全过滤掉。
结论
- 如果条件写在
ON中,不满足条件的子表记录会显示为NULL,但主表记录依然保留。 - 如果条件写在
WHERE中,会过滤掉不满足条件的记录,包括主表记录。
因此,是否保留主表记录取决于条件的写法和位置。