sql - SQL Server 2008 中用户定义的排名/分析函数

标签 sql sql-server analytics data-warehouse user-defined-functions

我正在计划将数据仓库迁移到 SQL Server 2008,并试图想办法从 SQL Server 2008 中的 Oracle 复制 LAG、LEAD、FIRST_VALUE 和 LAST_VALUE 分析函数。它们不包含在 SQL Server 2008 中,尽管窗口分析函数的基 native 制是(例如 ROW_NUMBER、RANK 和 DENSE_RANK 都存在)。

对于这些功能,可以通过创建一个子查询来实现相同的功能,该子查询使用 ROW_NUMBER 为每一行分配一个数字,然后对该查询进行自连接以查找具有附近行号的相关行(对于 LAG 和 LEAD) ,或行号 1(对于 FIRST_VALUE)。

我预计进行自连接会降低操作的效率:但我还没有 SQL Server 来测试它。因此,在没有实际评估性能的情况下,我想知道是否有更好的解决方法来避免自连接。

查看 user-defined aggregate functions 的文档, 可以想象,可以使用相同的代码结构来提供用户定义的分析函数。

所以我的问题是:您可以在用户定义的聚合函数后添加一个 OVER() 子句以将其作为解析函数调用吗?

如果是,是否每行调用一次 Terminate() 方法?是否需要采取任何特殊措施来确保按照 OVER() 子句中指定的顺序将行发送到您的 UDF?

最佳答案

我会使用自连接而不是 udfs。

您正在查看使用表访问的标量 UDFS,它几乎总是提供糟糕的性能(它是一个游标)。否则,您可能会使用 APPLY,但这也是逐行进行的。

此外,Oracle 函数不是聚合函数。用户定义的聚合仍然必须对结果集执行相同的处理。

请记住,无论如何,Oracle 在内部仍会进行一些逐行处理以计算出这些值。

因此,FIRST_VALUE 的 SQL Server 2005+ 示例(未测试)使用自连接。

请注意交叉连接以分离 FIRST_VALUE 和其余 2,因为结果集没有关系。如果您使用 UDF 或用户定义的聚合,那么很可能您必须从第一个结果集中的每行一遍又一遍地计算 FIRST_VALUE。

;WITH CTE AS
(
    SELECT
        department_id, last_name, salary,
        ROW_NUMBER() OVER (ORDER BY salary) AS ranking
    FROM employees
    WHERE department_id = 90
)
SELECT
    c1.department_id, c1.last_name, c1.salary,
    c2.last_name as Poorest
FROM
    CTE c1
    CROSS JOIN
    (SELECT last_name FROM CTE WHERE Ranking = 1) c2
ORDER BY
    c1.employee_id

关于sql - SQL Server 2008 中用户定义的排名/分析函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1740026/

相关文章:

sql - 如何在Hive中调用用户定义的函数?

sql-server - 在 Mac 上使用 iODBC 连接到 MS SQL Server

sql - 将转换后的格式更改为 ISO 日期 - SQL Server

sql-server - 勺子 : Truncate SQL Server table before exporting data from Hadoop

sql-server - 如何实现高性能 Excel VSTO 到 SQL Server?

Django A/B 拆分测试包(我发现没有一个是有据可查的和最新的。)

google-analytics - 生成Google Analytics(分析)和Omniture的链接

api - 我如何将 Google Analytics API 与 Zend OAuth 一起使用?

php - 构建 mysql 查询和/或 php 代码来关联不明确的数据点

mysql - 选择没有任何特定 Bar 事件的 Foo 对象