3

SQL Server 2008へのデータウェアハウスの移行を計画しており、SQL Server 2008でOracleからLAG、LEAD、FIRST_VALUE、およびLAST_VALUE分析関数を複製する方法を考えています。これらはSQL Server 2008には含まれていませんが、基本的なものです。ウィンドウ化された分析関数の機構は次のとおりです(たとえば、ROW_NUMBER、RANK、およびDENSE_RANKがすべて存在します)。

これらの関数の場合、ROW_NUMBERを使用して各行に番号を割り当てるサブクエリを作成し、そのクエリの自己結合を実行して、近くの行番号(LAGおよびLEADの場合)に関連する行を見つけることで、同じ機能を実現できます。行番号1(FIRST_VALUEの場合)。

自己結合を行うと、操作の効率が低下すると思いますが、これをテストするSQLServerはまだありません。したがって、実際にパフォーマンスを評価していなくても、自己結合を回避するより良い回避策があるかどうか疑問に思っています。

ユーザー定義の集計関数のドキュメントを見ると、同じコード構造を使用してユーザー定義の分析関数を提供できると考えられます。

だから私の質問は:ユーザー定義の集計関数の後にOVER()句を追加して、分析関数として呼び出すことができますか?

その場合、Terminate()メソッドは行ごとに1回呼び出されますか?OVER()句で指定された順序で行がUDFに送信されるようにするために、特別に必要なものはありますか?

4

2 に答える 2

3

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
于 2009-11-16T04:59:58.697 に答える
1

SQL サーバーでは、analytic は SSAS の一部です。FirstNonEmpty、LastNonEmpty、FirstChild、LastChild があります。これは、SQL サーバーの標準およびエンタープライズ バージョンに含まれています。ここを参照してください。つまり、立方体を構築したい場合です。

于 2009-11-16T17:13:10.013 に答える