如何用JOIN改写含CROSS APPLY的SQL语句?适配Trino/Presto
用JOIN改写CROSS APPLY的Trino/Presto实现
原SQL的核心逻辑是:为LN表的每一行,匹配同vnd_nbr、cltstyle且compdate更大的最早一条记录,最终返回主行+匹配行的所有字段。以下是两种适配Trino/Presto的改写方案:
方案1:子查询+等值JOIN(无重复日期场景)
如果(vnd_nbr, cltstyle, compdate)组合唯一,直接通过子查询找到每个主行对应的最小后续compdate,再关联回原表:
SELECT i.*, k.* FROM dbo.[LN] i JOIN dbo.[LN] k ON i.vnd_nbr = k.vnd_nbr AND i.cltstyle = k.cltstyle AND k.compdate = ( SELECT MIN(compdate) FROM dbo.[LN] j WHERE j.vnd_nbr = i.vnd_nbr AND j.cltstyle = i.cltstyle AND j.compdate > i.compdate ) ORDER BY i.VND_NBR;
方案2:窗口函数+JOIN(兼容重复日期场景)
如果存在同vnd_nbr、cltstyle下多条记录compdate相同的情况,用窗口函数给每条记录分组排序,确保只取最早的一条匹配记录:
WITH ranked_ln AS ( SELECT *, ROW_NUMBER() OVER (PARTITION BY vnd_nbr, cltstyle ORDER BY compdate) AS rn FROM dbo.[LN] ) SELECT i.*, k.* FROM ranked_ln i JOIN ranked_ln k ON i.vnd_nbr = k.vnd_nbr AND i.cltstyle = k.cltstyle AND k.rn = ( SELECT MIN(rn) FROM ranked_ln j WHERE j.vnd_nbr = i.vnd_nbr AND j.cltstyle = i.cltstyle AND j.compdate > i.compdate ) ORDER BY i.VND_NBR;
补充说明
两种方案都和原CROSS APPLY + TOP 1逻辑完全一致:仅返回有后续匹配记录的主行,且每个主行只匹配一条最早的后续记录。如果需要保留无匹配的主行(对应原SQL的OUTER APPLY),把JOIN改成LEFT JOIN即可。
内容的提问来源于stack exchange,提问作者Vineet Nair
相关产品推荐
相关产品推荐

