You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 21:25:21