sql >> データベース >  >> RDS >> Sqlserver

SQL Server 2012 の LAST_VALUE が奇妙な結果を返す

    SQL Server は、行がテーブルに挿入された順序を認識していません。特定の順序が必要な場合は、常に ORDER BY を使用してください .あなたの例では ORDER BY PK を含めない限り、あいまいです ORDER BY に .さらに、LAST_VALUE 注意しないと、関数は奇妙な結果を返す可能性があります - 以下を参照してください。

    MAX を使用して期待される結果を得ることができます または LAST_VALUE (SQLFiddle )。この場合、それらは同等です:

    SELECT
        PK, Id1, Id2
        ,MAX(PK) OVER (PARTITION BY Id1, Id2) AS MaxValue
        ,LAST_VALUE(PK) OVER (PARTITION BY Id1, Id2 ORDER BY PK rows between unbounded preceding and unbounded following) AS LastValue
    FROM
        Data
    ORDER BY id1, id2, PK
    

    このクエリの結果は、行が最初にテーブルに挿入された順序に関係なく同じになります。 INSERT を入れてみてください フィドルで異なる順序でステートメント。結果には影響しません。

    また、LAST_VALUE デフォルトのウィンドウで直感的に期待するようには動作しません (ORDER BY だけの場合) OVER で 句)。デフォルトのウィンドウは ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW です ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING であると予想していましたが、 . 良い説明 .この SO 回答へのリンクは、LAST_VALUE .そのため、行ウィンドウがクエリで明示的に指定されると、必要なものが返されます。

    行がテーブルに挿入された順序を知りたい場合、最も簡単な方法は IDENTITY .したがって、テーブルの定義は次のように変更されます:

    CREATE TABLE Data 
    (PK INT IDENTITY(1,1) PRIMARY KEY,
    Id1 INT,
    Id2 INT)
    

    INSERT すると PK の値を指定する必要はありません。 、サーバーはそれを自動的に生成します。多くのクライアントが同時にテーブルに挿入している場合でも、生成された値が一意であり、増加していることが保証されます (正のインクリメント パラメーターを使用)。生成された値の間にギャップがある場合がありますが、生成された値の相対的な順序により、どの行がどの行の後に挿入されたかがわかります。



    1. SQLServerで関数を作成する方法

    2. バルクSMSの送信は途中で停止します

    3. mysqlとphpを使用してソートされた行の位置を取得する方法

    4. SQLダンプからデータベースを復元するときにバイナリモードを有効にする