21

SQL Server 2005 で SQL クエリを実行しています。データベースから 2 つの列をクエリするだけでなく、それらと一緒に乱数の 1 つの列も返したいと考えています。私はこれを試しました:

select column1, column2, floor(rand() * 10000) as column3 
from table1

これはうまくいきますが、問題は、このクエリがすべての行で同じ乱数を返すことです。クエリを実行するたびに異なる数値になりますが、行ごとに変わることはありません。これを行うにはどうすれば、各行の新しい乱数を取得できますか?

4

12 に答える 12

41

これは古い投稿だと思います...しかし、ビューは必要ありません。

select column1, column2, 
  ABS(CAST(CAST(NEWID() AS VARBINARY) AS int)) % 10000 as column3 
from table1
于 2009-01-29T12:55:45.243 に答える
4

警告

ビューに関するAdamの回答は非常に非効率的であり、非常に大きなセットの場合、データベースをかなりの時間使用する可能性があります。定期的に、または本番環境で大きなテーブルにデータを入力する必要がある状況では、使用しないことを強くお勧めします.

代わりに、この回答を使用できます。

証拠:

CREATE VIEW vRandNumber
AS
SELECT RAND() as RandNumber

go 

CREATE FUNCTION RandNumber()
RETURNS float
AS
  BEGIN
  RETURN (SELECT RandNumber FROM vRandNumber)
  END

go 

create table bigtable(i int)

go 

insert into bigtable 
select top 100000 1 from sysobjects  a
join sysobjects b on 1=1

go 

select cast(dbo.RandNumber() * 10000 as integer) as r into #t from bigtable 
-- CPU (1607) READS (204639) DURATION (1551)

go

select ABS(CAST(CAST(NEWID() AS VARBINARY) AS int)) % 10000 as r  into #t1 
from bigtable
-- Runs 15 times faster - CPU (78) READS (809) DURATION (99)

プロファイラー トレース:

代替テキスト http://img519.imageshack.us/img519/8425/destroydbxu9.png

これは、0 から 9999 までの数値に対して十分にランダムであるという証拠です。

-- proof that stuff is random enough 
select avg(r) from #t
-- 5004
select STDEV(r) from #t
-- 2895.1999 

select avg(r) from #t1
-- 4992
select STDEV(r) from #t1
-- 2881.44 


select r,count(r) from #t
group by r 
-- 10000 rows returned 

select r,count(r) from #t1
group by r 
-- 10000 row returned 
于 2009-01-29T22:13:15.663 に答える
3
select RAND(CHECKSUM(NEWID()))
于 2010-12-07T03:00:56.787 に答える
3

Adam の回答は非常にうまく機能するので、承認済みとしてマークしました。回答を待っている間に、他のいくつかの (ややランダム性が低い) メソッドを含むこのブログ エントリも見つけました。カボイングの方法もその中にあった。

http://blog.sqlauthority.com/2007/04/29/sql-server-random-number-generator-script-sql-query/

于 2008-09-18T18:23:47.120 に答える
1

newid関数を使用して、乱数の代わりにUUIDを生成することを検討することをお勧めします。これらは生成されるたびに一意であることが保証されていますが、単純な乱数で重複が発生する可能性が非常に高くなります(使用目的によっては、後でエラーをデバッグするのが非常に困難になる可能性があります)。

于 2008-09-18T18:42:05.330 に答える
1

newid()私は非常にリソースを消費すると信じています。数百万レコードのテーブルでそのメソッドを試したのを思い出しますが、パフォーマンスはrand()ほど良くありませんでした。

于 2008-09-18T19:44:18.533 に答える
1

私のテストによると、上記の答えは 10000 の値を生成しません。1 から 10000 の間の乱数を生成している場合、これはおそらく大きな問題ではありませんが、1 から 5 の間の同じアルゴリズムは注目に値します。mod に 1 を追加します。

于 2009-08-03T14:45:09.320 に答える
1

rand()このスニペットは、0.0 から 1.0 の間の浮動小数点数を返すという点で、合理的な代用を提供しているようです。によって提供される最後の 3 バイトのみを使用するため、全体のランダム性は、推奨される回答からの変換とその後の moddingnewid()とはわずかに異なる場合があります。相対的なパフォーマンスをテストする機会はありませんでしたが、私の目的には十分に速い (そして十分にランダムである) ようです。VARBINARYINT

SELECT CAST(SubString(CONVERT(binary(16), newid()), 14, 3) AS INT) / 16777216.0 AS R
于 2009-11-13T20:03:58.877 に答える
1

乱数を扱うのにc#を使っています。それはずっときれいです。乱数と一意のキーのリストを返すために使用する関数があります。次に、行番号の uniqueKey を結合します。私は C# を使用しているため、乱数が収まる範囲を簡単に指定できます。

関数を作成する手順は次のとおりです 。 http://www.sqlwithcindy.com/2013/04/elegant-random-number-list-in-sql-server.html

私のクエリは次のようになります。

SELECT 
   rowNumber, 
   name, 
   randomNumber
FROM dbo.tvfRandomNumberList(1,10,100) 
INNER JOIN (select ROW_NUMBER() over (order by int_id) as 'rowNumber', name from client        
            )as clients
ON clients.rowNumber = uniqueKey
于 2013-04-25T21:41:13.683 に答える
1

UDF を使用する必要があります

最初:

CREATE VIEW vRandNumber
AS
SELECT RAND() as RandNumber

2番目:

CREATE FUNCTION RandNumber()
RETURNS float
AS
  BEGIN
  RETURN (SELECT RandNumber FROM vRandNumber)
  END

テスト:

SELECT dbo.RandNumber(), *
FROM <table>

上記はJeff の SQL Server ブログから借用

于 2008-09-18T17:54:38.627 に答える
1

SQLServer には、いくつかのオプションがあります。
1. 一度に 1 つの乱数で空の列を更新する while ループ
2. 乱数を返す関数を含む .net アセンブリ

于 2008-09-18T17:58:10.943 に答える
1

クエリ

select column1, column2, cast(new_id() as varchar(10)) as column3 
from table1
于 2008-09-18T17:58:20.177 に答える