左连接-子表的条件

99 阅读4分钟

前言

子表的字段也是可以加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 JOINON 条件中可以包含多个条件,通过 AND 来连接是完全有效的。你的这段 SQL 语句:

LEFT JOIN
`wk_shop` t4
ON
t4.steward_shop_id = a.steward_shop_id AND t4.type = 'ACTUAL_SITE'

表示在执行 LEFT JOIN 时,t4 表中的记录需要满足以下两个条件:

  1. t4.steward_shop_id = a.steward_shop_id
  2. t4.type = 'ACTUAL_SITE'

这两个条件会一同决定哪些记录可以被连接到主表中。如果满足条件的记录不存在,那么连接的结果中会用 NULL 来表示 t4 表中对应的字段。

注意点

  1. 执行顺序
    LEFT JOIN 的条件优先于 WHERE,即 ON 中的条件会在进行表连接时生效,而 WHERE 会在连接后的结果集中再进行筛选。
  2. 性能问题
    如果 wk_shop 表数据量大且未对 typesteward_shop_id 建立索引,查询性能可能会受到影响。可以考虑为这两个字段添加索引以提升查询效率。
  3. 逻辑清晰度
    这种写法逻辑清晰,通常在 LEFT JOIN 中直接加上 AND 条件是很常见的实践,不会影响语义或功能。

你可以直接使用这种写法,它在语法上是正确的,并且能够满足大多数需求。

问题

on里面的条件t4.type = 'ACTUAL_SITE'如果不满足,那么就是null,并不会过滤数据。而主表的where里面的子表条件t4.type = 'ACTUAL_SITE'如果不满足,则会过滤数据。对吗?

回答

完全正确!

ONWHERE 的区别

  1. ON 条件
    LEFT JOINON 条件是用于指定两个表之间如何进行匹配。即使 ON 条件中的部分条件(如 t4.type = 'ACTUAL_SITE')不满足,主表的数据仍然会保留,LEFT JOIN 结果中对应的子表字段会显示为 NULL
  2. WHERE 条件
    WHERE 条件是用来过滤最终的查询结果。如果在 WHERE 中加了对子表的条件(如 t4.type = 'ACTUAL_SITE'),会导致不满足条件的记录被过滤掉,这样主表中本应保留的记录也会丢失。

举例说明

假设有两张表:

main_table(主表)
idnamesteward_shop_id
1Alice101
2Bob102
wk_shop(子表)
steward_shop_idtypeshop_name
101ACTUAL_SITEShop A
102ONLINE_SITEShop 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';

结果:

idnamesteward_shop_idshop_name
1Alice101Shop A
2Bob102NULL

解释:
即使 Bobsteward_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';

结果:

idnamesteward_shop_idshop_name
1Alice101Shop A

解释:
WHERE 条件会过滤掉那些 t4.type != 'ACTUAL_SITE't4.type IS NULL 的记录,因此 Bob 的记录被完全过滤掉。


结论

  • 如果条件写在 ON 中,不满足条件的子表记录会显示为 NULL,但主表记录依然保留。
  • 如果条件写在 WHERE 中,会过滤掉不满足条件的记录,包括主表记录。

因此,是否保留主表记录取决于条件的写法和位置。