1

CHECKSUM_AGG私が予想していなかった 0 を返す条件がいくつかあるようです。議論されているものを見つけることができたのは 1 つだけです。つまり、重複した値が原因であるということです。DISTINCTこれはまたはで解決できますGROUP BY

また、あまり意味のないシナリオをさらにいくつか見つけました。1 つは上司から提供されたもので、もう 1 つはMSDNで見つけたものです。これらはどう説明したらいいのかわからない。シナリオを示すいくつかの SQL を次に示します。

SELECT
    CHECKSUM_AGG(T.Number) AS ChecksumAgggregate
FROM
(
    VALUES
        (2)
        , (3)
        , (4)
        , (5)
)AS T(Number)

DECLARE @t TABLE 
(
    Category VARCHAR(15),
    Value VARCHAR(10)
)

INSERT @t 
(
    Category
    , Value
)
VALUES 
    ('OneCharacter','a')
    ,('OneCharacter','b')
    ,('OneCharacter','c')
    ,('OneCharacter','d')

    ,('TwoCharacters','aa')
    ,('TwoCharacters','bb')
    ,('TwoCharacters','cc')
    ,('TwoCharacters','dd')

    ,('ThreeCharacters','aaa')
    ,('ThreeCharacters','bbb')
    ,('ThreeCharacters','ccc')
    ,('ThreeCharacters','ddd')

    ,('SixCharacters','aaaaaa')
    ,('SixCharacters','bbbbbb')
    ,('SixCharacters','cccccc')
    ,('SixCharacters','dddddd')

    ,('AllValues','a')
    ,('AllValues','b')
    ,('AllValues','c')
    ,('AllValues','d')
    ,('AllValues','aa')
    ,('AllValues','bb')
    ,('AllValues','cc')
    ,('AllValues','dd')
    ,('AllValues','aaa')
    ,('AllValues','bbb')
    ,('AllValues','ccc')
    ,('AllValues','ddd')
    ,('AllValues','aaaaaa')
    ,('AllValues','bbbbbb')
    ,('AllValues','cccccc')
    ,('AllValues','dddddd')

select 
    Category, CHECKSUM_AGG(CHECKSUM(Value)) 
from @t 
group by Category

select Category, Value, CHECKSUM(Value) ValueChecksum
from @t

CHECKSUM_AGGこれらのクエリからのこれらの例では、0 に過ぎません。最後のクエリはCHECKSUM、呼び出しに入力される値CHECKSUM_AGGが重複していないことを示しています。

CHECKSUM_AGG0 を返す原因を説明する答えが何であれ、これらの状況も説明できることを願っています。

4

1 に答える 1

3

これは、たとえば、行数が偶数の場合、または値の合計が特定の値 (たとえば 14) になる場合に発生する可能性があります。これらは両方とも 0 になります。

SELECT CHECKSUM_AGG(N)
FROM (VALUES (1),(2),(3),(4),(4)) AS T(N);

SELECT CHECKSUM_AGG(N)
FROM (VALUES (2),(3),(4),(5)) AS T(N);

しかし、これらはしません:

SELECT CHECKSUM_AGG(N)
FROM (VALUES (1),(2),(3),(4),(5)) AS T(N);

SELECT CHECKSUM_AGG(N)
FROM (VALUES (2),(3),(4),(6)) AS T(N);

14 は単なる偶然かもしれません (そして、6 行にわたってその値が発生することはありません)。これらのケースのいずれかが文書化されているかどうかはわかりません。

また、CHECKSUM_AGGは信頼できないと公式に文書化されています。つまり、データの変更を正確に反映していない可能性があります。このドキュメントでは、これについて詳しく説明していません。変更があったとしても、変更があったことを通知しない場合があると述べているだけです。(実際の文言は「ただし、チェックサムが変更されない可能性がわずかにあります。」)

とにかく、Michael Swart はそれが正しいことを発見したようCHECKSUM_AGGですXOR(ここに彼の証明があります):

CREATE TABLE #f(a FLOAT);
GO

INSERT #f VALUES (RAND());
GO 20

DECLARE @i INT = 0;
SELECT @i = @i ^ CHECKSUM(a) FROM #f;
SELECT @i, CHECKSUM_AGG(CHECKSUM(a)) FROM #f;
GO

DROP TABLE #f;
GO

彼が説明を続けているように、信頼できるチェックサムを生成する確率が急速に低下するため、値の範囲が非常に小さい場合、これは誤解を招く結果につながる可能性があります。

于 2012-08-16T20:15:20.163 に答える