RIGHT JOIN替代子查询:是否存在真实合理的应用场景?
关于RIGHT OUTER JOIN的使用疑问
我一直避免使用RIGHT OUTER JOIN,因为调整表顺序后用LEFT OUTER JOIN就能实现相同效果。但最近处理多表连接场景时,经常遇到这种模式:多个INNER JOIN组成的子查询被LEFT JOIN到主查询的多INNER JOIN序列里,脚本可读性差,还因为关联子查询导致性能不佳。
我可以用CTE、视图、临时表等方式优化,但用单个RIGHT JOIN就能消除子查询,而且多数情况下能提升性能。
问题1:能否仅用INNER JOIN和LEFT JOIN复现以下两个SELECT语句的结果?
DECLARE @A TABLE (Id INT) DECLARE @B TABLE (Id_A INT, Id_C INT) DECLARE @C TABLE (Id INT) INSERT @A VALUES (1),(2) INSERT @B VALUES (1,10),(2,20),(1,20) INSERT @C VALUES (10),(30) -- 需显示A的所有行,仅显示与B匹配且B与A匹配的C行 SELECT A.Id, T.Id FROM @A AS A LEFT JOIN ( SELECT * FROM @B AS B INNER JOIN @C AS C ON B.Id_C = C.Id) AS T ON A.Id = T.Id_A; -- 注:B与C必须匹配,仅当同时匹配A时才显示,否则为null SELECT A.Id, C.Id FROM @B AS B INNER JOIN @C AS C ON B.Id_C = C.Id RIGHT JOIN @A AS A ON B.Id_A = A.Id;
问题2:若均配有合适注释,更倾向于冗长的子查询还是RIGHT JOIN?过往文章都认为RIGHT JOIN冗余且易混淆,这个场景是否足以打破这种使用偏见?
回答
问题1:可以用INNER JOIN + LEFT JOIN复现结果
只需要调整表的连接顺序,把@A作为主表先做LEFT JOIN,再对匹配到的@B行和@C做INNER JOIN,逻辑和原语句完全一致,结果也相同:
SELECT A.Id, C.Id FROM @A AS A LEFT JOIN @B AS B ON A.Id = B.Id_A INNER JOIN @C AS C ON B.Id_C = C.Id;
这个语句的逻辑是:先保留@A的所有行,匹配对应的@B行,再从这些@B行里筛选出和@C匹配的记录,和原两个查询的输出完全一致。
问题2:倾向选择带清晰注释的RIGHT JOIN,该场景足以打破偏见
- 可读性层面:带注释的
RIGHT JOIN版本没有嵌套子查询,结构更扁平化,一眼就能明确@A是需要保留全量数据的核心表,同时清晰体现@B和@C必须先匹配再关联到@A的逻辑,比嵌套子查询更直观。 - 性能层面:
RIGHT JOIN版本不需要生成子查询的中间临时结果,数据库查询优化器更容易生成高效的执行计划,性能表现比嵌套子查询更稳定。 - 关于偏见的打破:"RIGHT JOIN冗余易混淆"的说法核心是"调整顺序就能用LEFT JOIN替代",但在多表连接场景下,如果需要保留的主表处于连接链末端,强行用LEFT JOIN可能需要打乱多个表的连接顺序,反而让业务逻辑变得别扭。而用RIGHT JOIN能更贴合"需要所有A的数据,以及同时匹配B和C的关联数据"的业务描述,只要注释清晰,完全不会增加理解成本。
因此在这个场景下,RIGHT JOIN是更优选择,足以打破"冗余易混淆"的偏见。
内容的提问来源于stack exchange,提问作者High Plains Grifter
相关产品推荐
相关产品推荐

