SQL Server 交叉应用

Posted

技术标签:

【中文标题】SQL Server 交叉应用【英文标题】:SQL Server CROSS APPLY 【发布时间】:2018-06-15 18:03:36 【问题描述】:

我正在尝试在此查询中添加CROSS APPLY。我以前从未做过,但一位同事建议这样做,这似乎是有道理的。我收到了一个语法错误。这是查询:

            SELECT
                i.IncidentID,
                i.AccountID,
                i.IncidentTypeID,
                i.IncidentStateID,
                i.CreateDate,
                i.LastModifyDate,
                i.LastModifyUser,
                (
                    SELECT
                        COUNT(*) 
                    FROM
                        Actions a
                    WHERE
                        a.IncidentID = i.IncidentID
                ) AS ActionCount
            CROSS APPLY
            (
                SELECT TOP 1
                    a.IncidentStateID,
                    a.LastModifyDate
                FROM Actions a
                WHERE a.IncidentID = i.IncidentID
                ORDER BY a.LastModifyDate DESC
            )
            FROM
                Incidents i
            WHERE i.IncidentTypeID = 44
            AND i.IncidentStateID = 7
            AND i.CreateDate >= ?
            AND i.CreateDate < ?

最终我需要获得最近发生事件的“Action”的a.IncidentStateID 和 a.LastModifyDate。这就是为什么它按 DESC 排序并只选择前 1 个。任何人都会看到语法问题。错误只是说General error: 20018 Incorrect syntax near the keyword 'ORDER'.。如果我删除它,它会转到另一段语法,依此类推。

【问题讨论】:

此链接可能会有所帮助:***.com/a/1139231/9236062 我不清楚为什么这里可能需要 CROSS APPLY。 IncidentsActions 之间有关系吗? CROSS APPLY 不会为您提供事件的最新行动。 CROSS APPLY 用于表之间没有共享键域的情况。 有关系。老实说,我不确定。我的同事说这是要走的路。我确实知道事件和操作之间存在一对多的关系,但由于我只获取最近的操作,因此重复不会成为问题。肯定会考虑走另一条路。 我想您可能正在寻找 CTE。 【参考方案1】:

Apply 应该在from 子句之后:

SELECT i.IncidentID, i.AccountID, i.IncidentTypeID,
        t.IncidentStateID, i.CreateDate, i.LastModifyDate, t.LastModifyUser,
        (SELECT COUNT(*) 
         FROM Actions a
         WHERE a.IncidentID = i.IncidentID
        ) AS ActionCount
FROM Incidents i CROSS APPLY( 
     SELECT TOP (1) a.IncidentStateID, a.LastModifyDate
     FROM Actions a
     WHERE a.IncidentID = i.IncidentID
     ORDER BY a.LastModifyDate DESC
     ) t
WHERE i.IncidentTypeID = 44 AND i.IncidentStateID = 7 AND 
      i.CreateDate >= ? AND i.CreateDate < ?;

【讨论】:

啊。谢谢!我在那里有它,但它不工作。现在可以了。 t 是干什么用的? 它是一个别名,就像您在查询中拥有 Actions a 一样。 明白了。谢谢!

以上是关于SQL Server 交叉应用的主要内容,如果未能解决你的问题,请参考以下文章

SQL Server 交叉应用不起作用?

SQL Server交叉表应用示例

SQL Server 交叉应用性能问题

如何在 SQL Server 的交叉应用联接中指定列名

在 SQL SERVER 中使用交叉应用进行更新

SQL Server - where + TVF/SVF、交叉应用、T-SQL