3から6までのランダムなint値を生成します


101

Microsoft SQL Serverで最小から最大までのランダムな整数値を生成することは可能ですか(3-9の例、15-99など)

私は知っています、0から最大まで生成できますが、最小境界を増やす方法は?

このクエリは、1から6までのランダムな値を生成します。3から6に変更する必要があります。

SELECT table_name, 1.0 + floor(6 * RAND(convert(varbinary, newid()))) magic_number 
FROM information_schema.tables

5秒後に追加

愚かな質問、申し訳ありません...

SELECT table_name, 3.0 + floor(4 * RAND(convert(varbinary, newid()))) magic_number 
FROM information_schema.tables

1
そこにある答えは、テーブルに対する管理者タイプの権限がある場合にのみ機能します。これを回避する方法は、フィールドの主キーをシードとして使用することでした。配布は素晴らしいものではありませんでしたが、目的を果たしました。
シャドウ

回答:


196

これにより、0〜9の乱数が生成されます。

SELECT ABS(CHECKSUM(NEWID()) % 10)

1から6

SELECT ABS(CHECKSUM(NEWID()) % 6) + 1

3から6

SELECT ABS(CHECKSUM(NEWID()) % 4) + 3

動的(Eilert Hjelmesethsコメントに基づく)

SELECT ABS(CHECKSUM(NEWID()) % (@max - @min + 1)) + @min

コメントに基づいて更新:

  • NEWID ランダムな文字列を生成します(返される行ごとに)
  • CHECKSUM 文字列の値を取り、数値を作成します
  • モジュラス(%)はその数値で除算し、余りを返します(つまり、最大値は、使用する数値よりも1小さい)
  • ABS 否定的な結果を肯定的にする
  • 次に、結果に1を加えて0の結果を排除します(ダイスの目をシミュレートするため)

2
これは私にトンを助けました!一括挿入用にランダムなキーを生成しようとすると、重複が発生し、一部のステートメントが失敗する場合があることに注意してください。でもありがとう!
Niklas 2017

3
1〜27の乱数を生成する必要がある場合はどうなりますか?つまり、範囲は9よりも大きいですか?
somegeek

4
私がロジックに従っている場合、この調整により正確に範囲を簡単に動的に設定できるようになります。ABS(CHECKSUM(NEWID()) % (@max - @min + 1)) + @min。私の側のいくつかのテストは良い結果をもたらしました。確かに正確であれば、この回答を含めることで少し改善できると思います。
Eilert Hjelmeseth

13

SQL Server 2008で質問への回答を追加したようです。

SELECT 3 + CRYPT_GEN_RANDOM(1) % 4 /*Random number between 3 and 6*/ 
FROM ...

この方法には、いくつかの欠点があります。

  1. これはNEWID()方法よりも遅い
  2. 行ごとに1回評価されますが、クエリオプティマイザーはこれを認識しないため、奇妙な結果になる可能性があります

しかし、私はそれを別のオプションとして追加すると思いました。


1
@ FSou1-はい。私CRYPT_GEN_RANDOMは本当に暗号的に安全な疑似乱数が必要な状況を意図していると思います。
マーティン・スミス

7

あなたはこれを行うことができます:

DECLARE @maxval TINYINT, @minval TINYINT
select @maxval=24,@minval=5

SELECT CAST(((@maxval + 1) - @minval) *
    RAND(CHECKSUM(NEWID())) + @minval AS TINYINT)

そして、それはこのリンクから直接取られました、私はこの答えに適切な信用を与える方法を本当に知りません。


5

Pinal Daveのサイトの素晴らしくシンプルなもの:

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

DECLARE @Random INT;
DECLARE @Upper INT;
DECLARE @Lower INT
SET @Lower = 3 ---- The lowest random number
SET @Upper = 7 ---- One more than the highest random number
SELECT @Random = ROUND(((@Upper - @Lower -1) * RAND() + @Lower), 0)
SELECT @Random

(@ Upper-にわずかな変更を加えて、1を加えた上位の数値を含めました。)


この例は別の投稿で見ました。ランダムな分布は提供されません。たとえば、Lowerは1、Upperは11なので、1から10までの乱数が必要です。1と10は、2〜8の半分のオカレンスを取得します。試してみてください。
nanonerd 2018年

4

単に:

DECLARE @MIN INT=3; --We define minimum value, it can be generated.
DECLARE @MAX INT=6; --We define maximum value, it can be generated.

SELECT @MIN+FLOOR((@MAX-@MIN+1)*RAND(CONVERT(VARBINARY,NEWID()))); --And then this T-SQL snippet generates an integer between minimum and maximum integer values.

このコードは、必要に応じて変更および編集できます。


1
このコードスニペットは歓迎されており、多少の助けになるかもしれませんが、質問への対処方法の説明含まれていれば大幅に改善されます。それがなければ、あなたの答えは教育的価値がはるかに低くなります。あなたが今尋ねている人だけでなく、将来的に読者のための質問に答えていることを忘れないでください!回答を編集して説明を追加し、適用される制限と前提を示してください。
Toby Speight 2017

4

シンプルで1行のコードは次のとおりです

これには、SQL Inbuild RAND()関数を使用します。

これは、2つの数値の間の乱数を生成する式です(RETURN INT範囲)。

ここで、aは最初の数値(Min)で、bは範囲の2番目の数値(Max)です

SELECT FLOOR(RAND()*(b-a)+a)

注:CAST関数またはCONVERT関数を使用して、INT範囲番号を取得することもできます。

(CAST(RAND()*(25-10)+10 AS INT))

例:

SELECT FLOOR(RAND()*(25-10)+10);

2つの数値の間の乱数を生成する式(RETURN DECIMAL範囲)は次のとおりです

SELECT RAND()*(b-a)+a;

例:

SELECT RAND()*(25-10)+10;

詳細はこちらを確認してください:https : //www.techonthenet.com/sql_server/functions/rand.php


1
リンク先の記事で述べたように、これは実際には値= Maxを生成しないことに注意してください。たとえば、10以上25以下の値でこれを行うには、SELECT FLOOR(RAND()*(25-10 + 1))+ 10
Shaun

1
SELECT ROUND((6 - 3 * RAND()), 0)

2
ある数値を他の数値よりも取得する可能性は、均等に分散されていません。これの出力をチェックしてください:SELECT ROUND((6 - 3 * 0.16), 0) SELECT ROUND((6 - 3 * 0.17), 0) SELECT ROUND((6 - 3 * 0.5), 0) SELECT ROUND((6 - 3 * 0.51), 0) SELECT ROUND((6 - 3 * 0.83), 0) SELECT ROUND((6 - 3 * 0.84), 0) ショー6のための16%は、変更、それが5である〜34%、〜34%は、それが3で4及び〜16%であること
マイク・デクラーク

切り捨ての方が丸めより優れている
MichaelChirico

0

関数としてのラマクの答え:

-- Create RANDBETWEEN function
-- Usage: SELECT dbo.RANDBETWEEN(0,9,RAND(CHECKSUM(NEWID())))
CREATE FUNCTION dbo.RANDBETWEEN(@minval TINYINT, @maxval TINYINT, @random NUMERIC(18,10))
RETURNS TINYINT
AS
BEGIN
  RETURN (SELECT CAST(((@maxval + 1) - @minval) * @random + @minval AS TINYINT))
END
GO

0
DECLARE @min INT = 3;
DECLARE @max INT = 6;
SELECT @min + ROUND(RAND() * (@max - @min), 0);

一歩一歩

DECLARE @min INT = 3;
DECLARE @max INT = 6;

DECLARE @rand DECIMAL(19,4) = RAND();
DECLARE @difference INT = @max - @min;
DECLARE @chunk INT = ROUND(@rand * @difference, 0);
DECLARE @result INT = @min + @chunk; 
SELECT @result;

したがって、ユーザー定義関数ではRAND()を使用できないことに注意してください。これに対する回避策(ソース:http : //blog.sqlauthority.com/2012/11/20/sql-server-using-rand-in-user-defined-functions-udf/)は、最初にビューを作成することです。

CREATE VIEW [dbo].[vw_RandomSeed]
AS
SELECT        RAND() AS seed

そしてランダム関数を作成します

CREATE FUNCTION udf_RandomNumberBetween
(
    @min INT,
    @max INT
)
RETURNS INT
AS
BEGIN
    RETURN @min + ROUND((SELECT TOP 1 seed FROM vw_RandomSeed) * (@max - @min), 0);
END

0

一般に:

select rand()*(@upper-@lower)+@lower;

あなたの質問のために:

select rand()*(6-3)+3;

<=>

select rand()*3+3;
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.