Tạo giá trị int ngẫu nhiên từ 3 đến 6


101

Có thể trong Microsoft SQL Server tạo giá trị int ngẫu nhiên từ Min đến Max không (ví dụ 3-9, 15-99, v.v.)

Tôi biết, tôi có thể tạo từ 0 đến Max, nhưng làm thế nào để tăng biên giới Min?

Truy vấn này tạo ra giá trị ngẫu nhiên từ 1 đến 6. Cần thay đổi nó từ 3 thành 6.

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

Đã thêm 5 giây sau :

Câu hỏi ngu ngốc, xin lỗi ...

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

1
Câu trả lời bạn có ở đó chỉ hoạt động nếu bạn có quyền loại quản trị viên trên bảng. Cách tôi giải quyết vấn đề này là sử dụng khóa chính trên trường làm hạt giống. Sự phân phối không xuất sắc, nhưng nó phục vụ mục đích.
Shadow

Câu trả lời:


196

Điều này tạo ra một số ngẫu nhiên giữa 0-9

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

1 đến 6

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

3 đến 6

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

Động (Dựa trên Nhận xét của Eilert Hjelmeseths)

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

Cập nhật dựa trên nhận xét:

  • NEWID tạo chuỗi ngẫu nhiên (cho mỗi hàng ngược lại)
  • CHECKSUM nhận giá trị của chuỗi và tạo số
  • modulus ( %) chia cho số đó và trả về phần còn lại (nghĩa là giá trị tối đa nhỏ hơn một số so với số bạn sử dụng)
  • ABS thay đổi kết quả tiêu cực thành tích cực
  • sau đó thêm một vào kết quả để loại bỏ kết quả 0 (để mô phỏng một lần tung xúc xắc)

2
điều này đã giúp tôi rất nhiều! chỉ cần nhớ nếu bạn đang cố gắng tạo các khóa ngẫu nhiên để chèn hàng loạt, điều này có thể gây ra các bản sao và một số câu lệnh sẽ không thành công. nhưng cảm ơn bạn!
Niklas

3
Điều gì sẽ xảy ra nếu tôi phải tạo số ngẫu nhiên từ 1 đến 27? tức là phạm vi lớn hơn thì 9?
somegeek

4
Nếu tôi tuân theo logic thì có vẻ như tinh chỉnh này sẽ cho phép bạn đặt động phạm vi một cách chính xác một cách dễ dàng. ABS(CHECKSUM(NEWID()) % (@max - @min + 1)) + @min. Một vài thử nghiệm của tôi đã mang lại kết quả tốt. Nếu nó thực sự chính xác, tôi nghĩ câu trả lời này có thể được cải thiện một chút bằng cách thêm nó vào.
Eilert Hjelmeseth

13

Tôi thấy bạn đã thêm câu trả lời cho câu hỏi của mình trong SQL Server 2008, bạn cũng có thể làm

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

Một số nhược điểm của phương pháp này là

  1. Điều này chậm hơn so với NEWID()phương pháp
  2. Ngay cả khi nó được đánh giá một lần mỗi hàng, trình tối ưu hóa truy vấn không nhận ra điều này có thể dẫn đến kết quả kỳ lạ .

nhưng chỉ nghĩ rằng tôi sẽ thêm nó như một tùy chọn khác.


1
@ FSou1 - Có. Tôi nghĩ rằng CRYPT_GEN_RANDOMnó thực sự dành cho các tình huống mà bạn cần một số ngẫu nhiên giả an toàn hơn về mặt mật mã.
Martin Smith,

7

Bạn có thể làm được việc này:

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

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

Và điều đó được lấy trực tiếp từ liên kết này , tôi thực sự không biết làm thế nào để cung cấp tín dụng thích hợp cho câu trả lời này.


5

Đẹp và đơn giản, từ trang của 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

(Tôi đã thực hiện một thay đổi nhỏ đối với @ Upper- để bao gồm số trên, thêm 1.)


Tôi đã thấy ví dụ này trong một bài đăng khác. Nó không cung cấp một phân phối ngẫu nhiên. Ví dụ: Lower là 1 và Upper là 11, vì vậy tôi muốn các số ngẫu nhiên từ 1 đến 10. Số 1 và số 10 có một nửa số lần xuất hiện là 2-8. Đi và kiểm tra nó ra.
nanonerd

4

Đơn giản:

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.

Bạn có thể thay đổi và chỉnh sửa mã này theo nhu cầu của mình.


1
Mặc dù đoạn mã này được hoan nghênh và có thể cung cấp một số trợ giúp, nhưng nó sẽ được cải thiện rất nhiều nếu nó bao gồm phần giải thích về cách nó giải quyết câu hỏi. Nếu không có điều đó, câu trả lời của bạn có ít giá trị giáo dục hơn nhiều - hãy nhớ rằng bạn đang trả lời câu hỏi cho độc giả trong tương lai, không chỉ người hỏi bây giờ! Vui lòng chỉnh sửa câu trả lời của bạn để thêm giải thích và đưa ra dấu hiệu về những hạn chế và giả định nào được áp dụng.
Toby Speight

4

Đây là dòng mã đơn giản và duy nhất

Đối với điều này, hãy sử dụng hàm SQL Inbuild RAND () .

Đây là công thức để tạo số ngẫu nhiên giữa hai số (RETURN INT Range)

Đây là số đầu tiên của bạn (Min) và b là số thứ hai (Max) trong phạm vi

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

Lưu ý: Bạn cũng có thể sử dụng hàm CAST hoặc CONVERT để lấy số phạm vi INT.

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

Thí dụ:

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

Đây là công thức để tạo số ngẫu nhiên giữa hai số (QUAY LẠI Dải KÝ TỰ)

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

Thí dụ:

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

Xem thêm chi tiết: https://www.techonthenet.com/sql_server/functions/rand.php


1
Lưu ý, như đã đề cập trong bài viết được liên kết, điều này sẽ không thực sự tạo ra giá trị = Max. Để làm điều này ví dụ cho các giá trị> = 10 và <= 25 bạn sẽ cần CHỌN SÀN (RAND () * (25-10 + 1)) + 10
Shaun

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

2
Cơ hội để có được một số hơn số kia không phải là lây lan. Kiểm tra đầu ra điều này: 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) cho thấy sự thay đổi 16% trong vòng 6, ~ 34% nó là 5, ~ 34% nó là 4 và ~ 16% nó là 3.
Mike de Klerk

cắt bỏ là vượt trội so với làm tròn
MichaelChirico

0

Câu trả lời của Lamak dưới dạng một hàm:

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

Từng bước một

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;

Lưu ý rằng một hàm do người dùng xác định không cho phép sử dụng RAND (). Một giải pháp cho điều này (nguồn: http://blog.sqlauthority.com/2012/11/20/sql-server-using-rand-in-user-defined-functions-udf/ ) là tạo chế độ xem trước.

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

và sau đó tạo hàm ngẫu nhiên

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

Nói chung:

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

Đối với câu hỏi của bạn:

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

<=>

select rand()*3+3;
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.