Hasilkan nomor acak dalam rentang 1 - 10

96

Karena pendekatan saya untuk pertanyaan tes yang saya kerjakan dalam pertanyaan ini tidak berhasil, saya mencoba sesuatu yang lain sekarang. Apakah ada cara untuk mengetahui random()fungsi pg agar saya hanya mendapatkan angka antara 1 dan 10?

KB22
sumber

Jawaban:

154

Jika dengan angka antara 1 dan 10 yang Anda maksud adalah float yang> = 1 dan <10, maka mudah saja:

select random() * 9 + 1

Ini dapat dengan mudah diuji dengan:

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

Jika Anda menginginkan bilangan bulat, yaitu> = 1 dan <10, caranya sederhana:

select trunc(random() * 9 + 1)

Dan lagi, tes sederhana:

# 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)
Klesun
sumber
pilih tanggal (e.created_at) + (trunc (random () * 20)) dari acara e; menghasilkan: ERROR: operator tidak ada: tanggal + presisi ganda Apakah trunc benar-benar mengembalikan bilangan bulat?
Bogdan Gusiev
3
trunc()mengembalikan tipe data yang sama dengan input (seperti yang dinyatakan di manual). Anda perlu mentransmisikan hasilnya ke integer:trunc(random() * 20)::int
a_horse_with_no_name
Saya ingin tahu apakah setidaknya dalam teori ada kemungkinan yang random()akan mengembalikan nilai <1 yang bila dikalikan dengan 9 akan> = 9 karena sifat tidak tepat dari tipe presisi ganda ? Dalam prakteknya bahkan jika mungkin itu akan menjadi sangat tidak mungkin tentu saja karena presisi 15 digit atau lebih.
1
Saya bermain-main dengan width_bucket(random(), 0, 1, 10)sebagai alternatif
Sepertinya ketakutan saya tidak berdasar meskipun saya akui saya sama sekali tidak mengerti matematika :-)
17

Untuk meringkas dan sedikit menyederhanakan, Anda dapat menggunakan:

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

Dan Anda dapat menguji ini seperti yang disebutkan oleh @ 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;
qd3v
sumber
2
The docs mengatakan "nilai acak di kisaran 0,0 <= x <1.0", sehingga setidaknya ada kesempatan teoritis ceil(random() * 10)menghasilkan 0 - Aku akan tetap floor.
1
Saya setuju dengan @JackDouglas, jadi untuk kisaran 1 - 10 seharusnyaSELECT floor(random() * 10 + 1);
SergiyKolesnikov
9

Jika Anda menggunakan SQL Server maka cara yang benar untuk mendapatkan integer adalah

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

Dimana

  • 'b' adalah batas atas
  • 'a' adalah batas bawah
Neha Jain
sumber
Hati-hati di sini, jika Anda menempatkan batas bawah 1 dan di atas 10, Anda hanya akan mendapatkan angka 1-> 9. Jawaban lain tampaknya berasumsi bahwa antara 1 dan 10 berarti 1-> 9 ... Saya akan menyarankan jika 'antara' tidak termasuk batas atas itu juga harus mengecualikan yang lebih rendah (yaitu 2-> 9). PILIH Cast (RAND () * ((b + 1) -a) + a sebagai int);
Morvael
Pertanyaan tersebut dengan jelas ditandai sebagai pertanyaan PostgreSQL.
Sebastian Palma
4

(trunc (random () * 10)% 10) + 1

hythlodayr
sumber
EROR: operator tidak ada: presisi ganda% integer
1
Dan mengapa Anda tetap menggunakan modulus? Logika ini tidak masuk akal. Jika Anda mendapatkan "pembungkusan", Anda tidak akan memiliki distribusi yang sama, dan jika Anda tidak mendapatkannya, Anda tidak membutuhkannya.
ErikE
1

Versi jawaban hythlodayr yang benar.

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

Keluaran dari truncharus diubah menjadi INTEGER. Tapi itu bisa dilakukan tanpa trunc. Jadi ternyata sederhana.

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

Menghasilkan keluaran INTEGER dalam kisaran [1, 10] yaitu 1 & 10 inklusif.

Untuk nomor apa pun (float), lihat jawaban pengguna80168. yaitu jangan mengubahnya menjadi INTEGER.

penulis mitos
sumber
0

Sebenarnya saya tidak tahu Anda ingin ini.

coba ini

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

Prosedur tersimpan ini memasukkan nomor rand ke dalam tabel. Awas, itu memasukkan nomor yang tak ada habisnya. Berhenti mengeksekusinya ketika Anda mendapatkan cukup nomor.

buat tabel untuk kursor:

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

PERGILAH

Buat tabel untuk memuat nomor Anda:

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

MEMASUKKAN SKRIP:

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

MEMBUAT DAN MELAKSANAKAN PROSEDUR:

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

Isi tabel Anda:

EXEC RandNumbers
Abu Khalil Mohamed
sumber
3
Pertanyaannya adalah tentang Postgres, bukan SQL Server
a_horse_with_no_name