Hasilkan nilai int acak dari 3 hingga 6

101

Apakah mungkin di Microsoft SQL Server menghasilkan nilai int acak dari Min hingga Max (contoh 3-9, 15-99 dll)

Saya tahu, saya dapat menghasilkan dari 0 ke Max, tetapi bagaimana cara meningkatkan batas Min?

Kueri ini menghasilkan nilai acak dari 1 hingga 6. Perlu mengubahnya dari 3 menjadi 6.

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

Ditambahkan 5 detik kemudian :

Pertanyaan bodoh, maaf ...

SELECT table_name, 3.0 + floor(4 * RAND(convert(varbinary, newid()))) magic_number 
FROM information_schema.tables
FSou1
sumber
1
Jawaban yang Anda miliki di sana hanya berfungsi jika Anda memiliki izin jenis admin di tabel. Cara saya menyiasatinya adalah dengan menggunakan kunci utama di lapangan sebagai benih. Distribusinya tidak brilian, tetapi memenuhi tujuan.
Bayangan

Jawaban:

196

Ini menghasilkan nomor acak antara 0-9

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

1 sampai 6

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

3 sampai 6

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

Dinamis (Berdasarkan Komentar Eilert Hjelmeseths)

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

Diperbarui berdasarkan komentar:

  • NEWID menghasilkan string acak (untuk setiap baris sebagai gantinya)
  • CHECKSUM mengambil nilai string dan membuat angka
  • modulus ( %) membagi dengan angka itu dan mengembalikan sisanya (artinya nilai maks kurang dari angka yang Anda gunakan)
  • ABS mengubah hasil negatif menjadi positif
  • lalu tambahkan satu ke hasil untuk menghilangkan 0 hasil (untuk mensimulasikan lemparan dadu)
orgtigger
sumber
2
ini sangat membantu saya! ingat saja jika Anda mencoba membuat kunci acak untuk penyisipan massal, ini dapat menyebabkan duplikat dan beberapa pernyataan akan gagal. tapi terima kasih!
Niklas
3
Bagaimana jika saya harus menghasilkan nomor acak antara 1 dan 27? yaitu kisaran lebih besar dari 9?
somegeek
4
Jika saya mengikuti logika, tampaknya tweak ini akan secara akurat memungkinkan Anda mengatur rentang secara dinamis dengan mudah. ABS(CHECKSUM(NEWID()) % (@max - @min + 1)) + @min. Beberapa tes di pihak saya membuahkan hasil yang baik. Jika memang akurat, saya rasa jawaban ini bisa sedikit ditingkatkan dengan memasukkannya.
Eilert Hjelmeseth
13

Saya melihat Anda telah menambahkan jawaban atas pertanyaan Anda di SQL Server 2008, Anda juga dapat melakukannya

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

Beberapa kelemahan dari metode ini adalah

  1. Ini lebih lambat dari NEWID()metode
  2. Meskipun dievaluasi sekali per baris, pengoptimal kueri tidak menyadari hal ini yang dapat menyebabkan hasil yang aneh .

tetapi hanya berpikir saya akan menambahkannya sebagai opsi lain.

Martin Smith
sumber
1
@ FSou1 - Ya. Saya pikir CRYPT_GEN_RANDOMini benar-benar dimaksudkan untuk situasi di mana Anda membutuhkan nomor acak semu yang lebih aman secara kriptografis.
Martin Smith
7

Kamu bisa melakukan ini:

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

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

Dan itu diambil langsung dari tautan ini , saya tidak benar-benar tahu bagaimana memberikan kredit yang tepat untuk jawaban ini.

Lamak
sumber
5

Bagus dan sederhana, dari situs 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

(Saya memang membuat sedikit perubahan pada @ Atas- untuk memasukkan angka atas, menambahkan 1.)

Adrian Carr
sumber
Saya melihat contoh ini di postingan lain. Ini tidak memberikan distribusi acak. Misalnya, Bawah 1 dan Atas 11 jadi saya ingin angka acak dari 1 sampai 10. Angka 1 dan 10 mendapatkan setengah kejadian sebagai 2-8. Pergi dan ujilah.
nanonerd
4

Secara sederhana:

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.

Anda dapat mengubah dan mengedit kode ini untuk kebutuhan Anda.

MERT DOĞAN
sumber
1
Meskipun cuplikan kode ini diterima, dan mungkin memberikan bantuan, akan sangat ditingkatkan jika menyertakan penjelasan tentang bagaimana cara menjawab pertanyaan. Tanpanya, jawaban Anda kurang memiliki nilai edukatif - ingatlah bahwa Anda menjawab pertanyaan untuk pembaca di masa depan, bukan hanya orang yang bertanya sekarang! Harap edit jawaban Anda untuk menambahkan penjelasan, dan berikan indikasi batasan dan asumsi apa yang berlaku.
Toby Speight
4

Ini adalah satu baris kode

Untuk ini gunakan fungsi SQL Inbuild RAND () .

Berikut rumus untuk menghasilkan bilangan random antara dua bilangan (RETURN INT Range)

Di sini a adalah Angka Pertama Anda (Min) dan b adalah Angka Kedua (Maks) dalam Rentang

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

Catatan: Anda dapat menggunakan fungsi CAST atau CONVERT juga untuk mendapatkan nomor rentang INT.

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

Contoh:

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

Berikut rumus untuk menghasilkan bilangan random antara dua bilangan (RETURN DECIMAL Range)

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

Contoh:

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

Detail lebih lanjut periksa ini: https://www.techonthenet.com/sql_server/functions/rand.php

Manjunath Bilwar
sumber
1
Perhatikan, seperti yang disebutkan dalam artikel terkait, ini tidak akan benar-benar menghasilkan nilai = Max. Untuk melakukan ini misalnya untuk nilai> = 10 dan <= 25 Anda akan membutuhkan SELECT FLOOR (RAND () * (25-10 + 1)) + 10
Shaun
1
SELECT ROUND((6 - 3 * RAND()), 0)
greg121
sumber
2
Peluang untuk mendapatkan satu nomor di atas yang lain tidak tersebar merata. Periksa outputnya: 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) Menunjukkan bahwa 16% perubahan untuk 6, ~ 34% itu adalah 5, ~ 34% itu adalah 4 dan ~ 16% itu adalah 3.
Mike de Klerk
pemotongan lebih unggul daripada pembulatan
MichaelChirico
0

Fungsi jawaban Lamak :

-- 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
AndreFeijo
sumber
0
DECLARE @min INT = 3;
DECLARE @max INT = 6;
SELECT @min + ROUND(RAND() * (@max - @min), 0);

Selangkah demi selangkah

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;

Perhatikan bahwa fungsi yang ditentukan pengguna tidak mengizinkan penggunaan RAND (). Solusi untuk ini (sumber: http://blog.sqlauthority.com/2012/11/20/sql-server-using-rand-in-user-defined-functions-udf/ ) adalah membuat tampilan terlebih dahulu.

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

dan kemudian buat fungsi acak

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
Mike de Klerk
sumber
0

Secara umum:

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

Untuk pertanyaan Anda:

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

<=>

select rand()*3+3;
Zeinab
sumber