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.