重构不含OUTER APPLY的SQL代码:改用LEFT JOIN实现
将OUTER APPLY替换为LEFT JOIN重构SQL语句
原SQL通过OUTER APPLY关联子查询,为每条记录找到同服务器、同工作中心下,停机开始时间早于当前记录停机结束时间的最新生产订单。下面是用LEFT JOIN结合窗口函数实现相同逻辑的重构方案:
重构后的SQL
SELECT cur.downtimedataid, cur.serverid, cur.downtimestart, cur.downtimefinish, cur.downtimeinfo1, cur.downtimeinfo2, cur.newproductionorderid, cur.plantid, cur.workcenterid, cur.dm_plantid, prev.previousorderid FROM bcs cur LEFT JOIN ( SELECT newproductionorderid AS previousorderid, serverid, workcenterid, downtimestart, -- 按serverid+workcenterid分组,按停机开始时间倒序编号 ROW_NUMBER() OVER (PARTITION BY serverid, workcenterid ORDER BY downtimestart DESC) AS rn FROM bcs ) prev ON cur.serverid = prev.serverid AND cur.workcenterid = prev.workcenterid AND prev.downtimestart < cur.downtimefinish AND prev.rn = 1; -- 仅保留分组内最新的前序记录
逻辑说明
- 子查询中用
ROW_NUMBER()窗口函数,按serverid和workcenterid分组,每组内按downtimestart倒序给记录编号,编号为1的就是该分组内符合时间条件的最新记录。 - 通过
LEFT JOIN关联原表cur和预处理后的子查询结果,关联条件完全匹配原OUTER APPLY的筛选规则,同时通过prev.rn = 1锁定最新的前序订单。 - 该写法和原
OUTER APPLY逻辑完全一致:返回原表所有记录,匹配不到前序订单时previousorderid为NULL。
内容的提问来源于stack exchange,提问作者porshe25
相关产品推荐
相关产品推荐

