Tạo một số ngẫu nhiên trong phạm vi 1 - 10


95

Vì cách tiếp cận của tôi cho một truy vấn thử nghiệm mà tôi đã thực hiện trong câu hỏi này không thành công, tôi đang thử một thứ khác. Có cách nào để nói với random()hàm của pg để giúp tôi chỉ có các số từ 1 đến 10 không?

Câu trả lời:


152

Nếu theo các số từ 1 đến 10, bạn có nghĩa là bất kỳ số float nào> = 1 và <10, thì thật dễ dàng:

select random() * 9 + 1

Điều này có thể dễ dàng kiểm tra với:

# select min(i), max(i) from (
    select random() * 9 + 1 as i from generate_series(1,1000000)
) q;
       min       |       max
-----------------+------------------
 1.0000083274208 | 9.99999571684748
(1 row)

Nếu bạn muốn các số nguyên> = 1 và <10, thì thật đơn giản:

select trunc(random() * 9 + 1)

Và một lần nữa, thử nghiệm đơn giản:

# select min(i), max(i) from (
    select trunc(random() * 9 + 1) as i from generate_series(1,1000000)
) q;
 min | max
-----+-----
   1 |   9
(1 row)

chọn ngày (e.create_at) + (trunc (random () * 20)) từ các sự kiện e; kết quả là: ERROR: không tồn tại toán tử: ngày + độ chính xác kép Trunc có thực sự trả về số nguyên không?
Bogdan Gusiev

3
trunc()trả về cùng kiểu dữ liệu với đầu vào (như đã nêu trong sách hướng dẫn). Bạn cần phải đúc kết quả đến một số nguyên:trunc(random() * 20)::int
a_horse_with_no_name

Tôi tự hỏi liệu ít nhất về lý thuyết có thể random()trả về giá trị <1 mà khi nhân với 9 sẽ là> = 9 do bản chất không chính xác của kiểu chính xác kép không? Trong thực tế, ngay cả khi điều đó có thể xảy ra, tất nhiên sẽ không thể biến mất vì độ chính xác của 15 chữ số.

1
Tôi đang đùa giỡn với width_bucket(random(), 0, 1, 10)như một sự thay thế

Dường như nỗi sợ hãi của tôi đã có căn cứ mặc dù tôi thú nhận tôi không hiểu toán học ở tất cả :-)

17

Để tóm tắt và đơn giản hóa một chút, bạn có thể sử dụng:

-- 0 - 9
select floor(random() * 10);
-- 0 - 10
SELECT floor(random() * (10 + 1));
-- 1 - 10
SELECT ceil(random() * 10);

Và bạn có thể kiểm tra điều này như được đề cập bởi @ user80168

-- 0 - 9
SELECT min(i), max(i) FROM (SELECT floor(random() * 10) AS i FROM generate_series(0, 100000)) q;
-- 0 - 10
SELECT min(i), max(i) FROM (SELECT floor(random() * (10 + 1)) AS i FROM generate_series(0, 100000)) q;
-- 1 - 10
SELECT min(i), max(i) FROM (SELECT ceil(random() * 10) AS i FROM generate_series(0, 100000)) q;

2
Các tài liệu nói rằng "giá trị ngẫu nhiên trong phạm vi 0,0 <= x <1,0", vì vậy ít nhất có cơ hội lý thuyết ceil(random() * 10)dẫn đến kết quả là 0 - tôi sẽ kiên định floor.

1
Tôi đồng ý với @JackDouglas, vì vậy, đối với phạm vi 1 - 10 thì nênSELECT floor(random() * 10 + 1);
SergiyKolesnikov

9

Nếu bạn đang sử dụng SQL Server thì cách chính xác để lấy số nguyên là

SELECT Cast(RAND()*(b-a)+a as int);

Ở đâu

  • 'b' là giới hạn trên
  • 'a' là giới hạn thấp hơn

Hãy cẩn thận ở đây, nếu bạn đặt giới hạn dưới là 1 và trên là 10, bạn sẽ chỉ nhận được số 1-> 9. Các câu trả lời khác dường như giả định rằng Từ 1 đến 10 có nghĩa là 1-> 9 ... Tôi sẽ đề xuất nếu 'giữa' loại trừ giới hạn trên thì nó cũng nên loại trừ giới hạn dưới (tức là 2-> 9). SELECT Cast (RAND () * ((b + 1) -a) + a as int);
Morvael

Câu hỏi được gắn thẻ rõ ràng là một câu hỏi PostgreSQL.
Sebastian Palma

4

(trunc (ngẫu nhiên () * 10)% 10) + 1


LỖI: nhà điều hành không tồn tại: độ chính xác kép% số nguyên

1
Và tại sao bạn sẽ sử dụng modulus? Logic này không có ý nghĩa. Nếu bạn nhận được bất kỳ "gói" nào, bạn sẽ không có phân phối bằng nhau và nếu bạn không nhận được bất kỳ gói nào, thì bạn không cần nó.
ErikE

1

Phiên bản chính xác của câu trả lời của hythlodayr.

-- ERROR:  operator does not exist: double precision % integer
-- LINE 1: select (trunc(random() * 10) % 10) + 1

Đầu ra từ truncphải được chuyển đổi thành INTEGER. Nhưng nó có thể được thực hiện mà không cần trunc. Vì vậy, nó hóa ra là đơn giản.

select (random() * 9)::INTEGER + 1

Tạo đầu ra INTEGER trong phạm vi [1, 10] tức là bao gồm cả 1 và 10.

Đối với bất kỳ số nào (số nổi), hãy xem câu trả lời của user80168. tức là chỉ cần không chuyển đổi nó thành INTEGER.


0

Thực sự tôi không biết bạn muốn điều này.

thử cái này

INSERT INTO my_table (my_column)
SELECT
    (random() * 10) + 1
;

0

Thủ tục được lưu trữ này sẽ chèn một số rand vào một bảng. Nhìn ra, nó chèn một số vô tận. Ngừng thực hiện nó khi bạn nhận đủ số.

tạo bảng cho con trỏ:

CREATE TABLE [dbo].[SearchIndex](
[ID] [int] IDENTITY(1,1) NOT NULL,
[Cursor] [nvarchar](255) NULL) 

ĐI

Tạo một bảng để chứa các số của bạn:

CREATE TABLE [dbo].[ID](
[IDN] [int] IDENTITY(1,1) NOT NULL,
[ID] [int] NULL)

CHÈN KHẮC PHỤC:

INSERT INTO [SearchIndex]([Cursor])  SELECT N'INSERT INTO ID  SELECT   FLOOR(rand() * 9 + 1)  SELECT COUNT (ID) FROM ID

TẠO VÀ THỰC HIỆN QUY TRÌNH:

CREATE PROCEDURE [dbo].[RandNumbers] AS
BEGIN
Declare  CURSE  CURSOR  FOR (SELECT  [Cursor] FROM [dbo].[SearchIndex]  WHERE [Cursor] IS NOT NULL)
DECLARE @RandNoSscript NVARCHAR (250)
OPEN CURSE
FETCH NEXT FROM CURSE
INTO @RandNoSscript 
WHILE @@FETCH_STATUS IS NOT NULL 
BEGIN
Print @RandNoSscript
EXEC SP_EXECUTESQL @RandNoSscript;  
 END
 END
GO

Điền vào bảng của bạn:

EXEC RandNumbers

3
Câu hỏi đặt ra là về Postgres, không SQL Server
a_horse_with_no_name
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.