将相关子查询重写为 CROSS APPLY
Posted
技术标签:
【中文标题】将相关子查询重写为 CROSS APPLY【英文标题】:Rewrite correlated subquery to CROSS APPLY 【发布时间】:2021-03-15 13:39:57 【问题描述】:所以我尝试使用CROSS APPLY
,但似乎无法正确使用。
我有一些类似这样的查询:
SELECT COL1, COL2
FROM dbo.tableA AS A
WHERE COL3 = (SELECT MAX(COL4)
FROM dbo.tableA AS B
WHERE A.COL1 = B.COL1) AS SUB
我试试这个:
SELECT COL1, COL2
FROM dbo.tableA AS A
CROSS APPLY (SELECT MAX(COL4) AS MAX_DATE
FROM TABLEA AS B
WHERE A.COL1 = B.COL1) AS SUB
但是当我使用CROSS APPLY
时,我总是返回更多行。我的错在哪里?
【问题讨论】:
【参考方案1】:如果您希望这两个查询同样工作,您在第二个查询中缺少 WHERE
:
SELECT COL1, COL2
FROM dbo.tableA AS A
CROSS APPLY (SELECT MAX(COL4) AS MAX_DATE
FROM TABLEA AS B
WHERE A.COL1 = B.COL1) AS SUB
WHERE A.COL3 = SUB.MAX_DATE;
【讨论】:
谢谢,当然 :-)。将子查询放在表值函数中是否有助于提高性能。我在桌子上有一个 POC 索引。还是该函数只会帮助使代码更具可读性? PS它说我必须等待才能接受。 老实说,这不太可能有所不同,但您可以通过测试轻松找到。 我仍然看到 CROSS APPLY 版本的行数更多。你能解释一下吗? 不,@xhr489,我没有样本数据或预期结果。上面的应该是一样的,所以我怀疑这里没有别的了。 可能不会有任何区别,但是您需要set statistics time on
并比较 逻辑读取 选择最少的,或者如果相同无关紧要。 【参考方案2】:
除了APPLY
重写,因为这是一个自连接,它也可以通过MAX
窗口聚合来完成:
SELECT COL1, COL2
FROM (
SELECT *,
MAX(COL4) OVER (PARTITION BY COL1) AS mx
FROM dbo.tableA
) AS A
WHERE COL3 = mx
【讨论】:
谢谢,你能问一下为什么两个版本的结果略有不同吗? 没有样本数据,没有。您发布的查询是否完整? 没有外部查询在 where 子句中有额外的谓词 我找到了原因,我错过了一些东西 :-)以上是关于将相关子查询重写为 CROSS APPLY的主要内容,如果未能解决你的问题,请参考以下文章
Hive 上的 CROSS APPLY SQL Server 查询
使用 CROSS APPLY 与 OUTER APPLY 连接查询
使用 CROSS APPLY 与 OUTER APPLY 连接查询