3'ten 6'ya kadar rastgele int değeri oluşturun


104

Microsoft SQL Server'da Min'den Max'e rastgele int değeri üretmesi mümkün mü (3-9 örnek, 15-99 vb.)

Biliyorum, 0'dan Max'e kadar üretebilirim, ancak Min sınırı nasıl artırılır?

Bu sorgu 1'den 6'ya kadar rastgele bir değer üretir. 3'ten 6'ya değiştirilmesi gerekir.

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

5 saniye sonra eklendi :

Aptal soru, üzgünüm ...

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

1
Oradaki cevap, yalnızca tabloda yönetici türü izinleriniz varsa işe yarar. Bunu aşma şeklim, tarladaki birincil anahtarı tohum olarak kullanmaktı. Dağıtım mükemmel değildi ama amaca hizmet etti.
— Gölge

Yanıtlar:


199

Bu, 0-9 arasında rastgele bir sayı oluşturur

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

1'den 6'ya

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

3 ila 6

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

Dinamik (Eilert Hjelmeseths Yorumuna Göre)

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

Yorumlara göre güncellendi:

  • NEWID rastgele dizge üretir (dönüşteki her satır için)
  • CHECKSUM dizenin değerini alır ve sayı oluşturur
  • modül ( %) bu sayıya böler ve kalanı döndürür (yani maksimum değer, kullandığınız sayıdan bir eksiktir)
  • ABS olumsuz sonuçları olumluya çevirir
  • sonra 0 sonucu elemek için sonuca bir ekleyin (zar atma simülasyonu için)

2
bu bana bir ton yardımcı oldu! toplu eklemeler için rastgele anahtarlar oluşturmaya çalışıyorsanız, bu yinelemelere neden olabilir ve bazı ifadeler başarısız olur. ama teşekkür ederim!
— Niklas

3
1 ile 27 arasında rastgele sayı oluşturmam gerekirse ne olur? yani aralık 9'dan büyük mü?
— somegeek

4
Mantığı takip ediyorsam, bu ince ayar, aralığı dinamik olarak kolayca ayarlamanıza izin verecek gibi görünüyor. ABS(CHECKSUM(NEWID()) % (@max - @min + 1)) + @min. Benim tarafımdan yapılan birkaç test iyi sonuçlar verdi. Eğer gerçekten doğruysa, bu cevabın onu dahil ederek biraz iyileştirilebileceğini düşünüyorum.
— Eilert Hjelmeseth

13

Görüyorum ki SQL Server 2008'de sorunuza bir cevap eklediniz mi?

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

Bu yöntemin birkaç dezavantajı şunlardır:

  1. Bu NEWID()yöntemden daha yavaştır
  2. Her satırda bir kez değerlendirilmesine rağmen, sorgu iyileştirici bunun farkına varmaz ve bu da garip sonuçlara yol açabilir .

ama bunu başka bir seçenek olarak ekleyeceğimi düşündüm.


1
@ FSou1 - Evet. Sanırım CRYPT_GEN_RANDOMgerçekten daha kriptografik olarak güvenli bir sözde rastgele sayıya ihtiyaç duyduğunuz durumlar için tasarlandı.
— Martin Smith

7

Bunu yapabilirsiniz:

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

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

Ve bu doğrudan bu bağlantıdan alındı , bu cevaba nasıl uygun şekilde itibar edeceğimi gerçekten bilmiyorum.


5

Pinal Dave'in sitesinden güzel ve basit:

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

(Üst sayıyı dahil etmek için @ Üstte küçük bir değişiklik yaptım, 1. ekledim.)


Bu örneği başka bir gönderide gördüm. Rastgele dağılım sağlamaz. Örneğin, Alt 1 ve Üst 11, bu yüzden 1'den 10'a kadar rastgele sayılar istiyorum. 1 ve 10, 2-8 gibi oluşumların yarısını alıyor. Git ve test et.
— nanonerd

4

Basitçe:

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.

Bu kodu ihtiyaçlarınız için değiştirebilir ve düzenleyebilirsiniz.


1
Bu kod parçacığı memnuniyetle karşılanır ve biraz yardım sağlayabilir, ancak soruyu nasıl ele aldığına dair bir açıklama içeriyorsa büyük ölçüde geliştirilecektir . Bu olmadan, cevabınızın çok daha az eğitimsel değeri vardır - soruyu yalnızca şu anda soran kişi değil, gelecekte okuyucular için de cevaplayacağınızı unutmayın! Lütfen açıklama eklemek için cevabınızı düzenleyin ve hangi sınırlamaların ve varsayımların geçerli olduğuna dair bir gösterge verin.
— Toby Speight

4

İşte basit ve tek satır kod

Bunun için SQL Inbuild RAND () kullanın işlevini kullanın.

İki sayı arasında rastgele sayı üretme formülü (RETURN INT Range)

Burada a İlk Numaranız (Min) ve b Aralıktaki İkinci Numaradır (Maks)

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

Not: INT aralık numarasını almak için CAST veya CONVERT işlevini de kullanabilirsiniz.

(KULLANMA (RAND () * (25-10) +10 INT OLARAK))

Misal:

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

İşte iki sayı arasında rastgele sayı üretme formülü (GERİ DÖNÜŞ DEKİMAL Aralık)

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

Misal:

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

Daha fazla ayrıntı bunu kontrol edin: https://www.techonthenet.com/sql_server/functions/rand.php


1
Unutmayın, bağlantılı makalede belirtildiği gibi bu aslında değerler üretmeyecektir = Max. Bunu yapmak için, örneğin> = 10 ve <= 25 değerleri için SEÇİM TABANI (RAND () * (25-10 + 1)) + 10
— Shaun

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

2
Bir sayıyı diğerine alma şansı eşit olarak dağılmamıştır. Bunun çıktısını kontrol edin: 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 için% 16 değişim, ~% 34,% 5, ~% 34, 4 ve ~% 16 3 olduğunu gösterir.
— Mike de Klerk

kesme, yuvarlamadan üstündür
— MichaelChirico

0

Bir işlev olarak Lamak'ın cevabı:

-- 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);

Adım adım

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;

Kullanıcı tanımlı bir işlevin bu nedenle RAND () kullanımına izin vermediğini unutmayın. Bunun için bir çözüm (kaynak: http://blog.sqlauthority.com/2012/11/20/sql-server-using-rand-in-user-defined-functions-udf/ ) önce bir görünüm oluşturmaktır.

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

ve sonra rastgele işlevi oluşturun

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

Genel olarak:

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

Sorunuz için:

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

<=>

select rand()*3+3;
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.