式rand(checksum(newid()))
は、乱数を生成するためによく使用されます。
いくつかのテスト データを生成しているときに、次のステートメントを実行しました。
select rand(checksum(newid())) R1, rand(checksum(newid())) R2
from ftSequence(3)
ここで、単一の列とその行の値(引数と同じ数) をftSequence(N)
返すテーブル関数です。これを実行すると、非常に期待されるデータが得られました。N
1, 2, 3 ... N
N
R1 R2
---------------------- ----------------------
0,817 0,9515
0,3043 0,3947
0,5336 0,7963
次に、各列の合計を見つける必要があり、次のようにしました。
select sum(rand(checksum(newid()))) S1, sum(rand(checksum(newid()))) S2
from ftSequence(3)
驚いたことに、各列に同じ数字が表示されました。
S1 S2
---------------------- ----------------------
1,2276 1,2276
なぜそれが起こるのですか?avg
、min
およびmax
集約関数の同じ動作。クエリオプティマイザーですか、それともロジックがありませんか?
コメントの後にさらに観察。
sum(rand(checksum(newid())))
CTEまたはサブクエリに配置する
select
(select sum(rand(checksum(newid()))) from ftSequence(3)) S1,
(select sum(rand(checksum(newid()))) from ftSequence(3)) S2
また
select sum(R1) S1, sum(R2) S2
from (
select rand(checksum(newid())) R1, rand(checksum(newid())) R2
from ftSequence(3)
) R
のようなトリックを行うだけでなく、
select
sum(rand(checksum(newid()))) S1
, sum(rand(checksum(newid())) + 0) S2
from ftSequence(3)
働き、異なる値になりました
S1 S2
---------------------- ----------------------
0,7349 1,478
それに満足し、いくつかの異なる行を複数生成する必要があったため、avg(rand(checksum(newid()))) from ftSequence(3)
次のことを行いました
select R.*
from ftSequence(3) S1
cross join (
select
avg(rand(checksum(newid()))) R1,
avg(rand(checksum(newid())) + 0) R2
from ftSequence(3)
) R
そして次の結果を得ました:
R1 R2
---------------------- ----------------------
0,6464 0,4501
0,6464 0,4501
0,6464 0,4501
この時点で、正しい結果なのか、それとも値がすべてランダムであるべきなのか、自分で答えることができませんでした。すべての値をランダムにする方法は何ですか?