Wygeneruj liczbę losową z zakresu 1 - 10

99

Ponieważ moje podejście do zapytania testowego, nad którym pracowałem w tym pytaniu, nie wyszło, próbuję teraz czegoś innego. Czy istnieje sposób, aby powiedzieć random()funkcji pg, aby otrzymywała tylko liczby od 1 do 10?

KB22
źródło

Odpowiedzi:

159

Jeśli przez liczby od 1 do 10 masz na myśli dowolną liczbę zmiennoprzecinkową> = 1 i <10, to jest to łatwe:

select random() * 9 + 1

Można to łatwo przetestować za pomocą:

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

Jeśli chcesz liczb całkowitych, czyli> = 1 i <10, to jest proste:

select trunc(random() * 9 + 1)

I znowu, prosty test:

# 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
źródło
wybierz datę (e.created_at) + (trunc (random () * 20)) ze zdarzeń e; skutkuje: BŁĄD: operator nie istnieje: data + podwójna precyzja Czy obcięcie naprawdę zwraca liczby całkowite?
Bogdan Gusiev
3
trunc()zwraca ten sam typ danych co wejście (zgodnie z opisem w instrukcji). Musisz rzutować wynik na liczbę całkowitą:trunc(random() * 20)::int
a_horse_with_no_name
Zastanawiam się, czy przynajmniej w teorii jest możliwe, random()że zwróci wartość <1, która po pomnożeniu przez 9 będzie> = 9 ze względu na niedokładną naturę typu podwójnej precyzji ? W praktyce, nawet jeśli jest to możliwe, byłoby to bardzo mało prawdopodobne z powodu 15-cyfrowej dokładności.
1
Ja bawiąc się width_bucket(random(), 0, 1, 10)jako alternatywny
Wygląda na to, że moje obawy były bezpodstawne, chociaż przyznaję, że w ogóle nie rozumiem matematyki :-)
17

Podsumowując i nieco upraszczając, możesz użyć:

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

Możesz to przetestować, jak wspomniał @ 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
źródło
2
Dokumenty mówią, że „losowa wartość w zakresie 0,0 <= x <1,0”, więc istnieje przynajmniej teoretyczna szansa ceil(random() * 10)na 0 - trzymałbym się floor.
1
Zgadzam się z @JackDouglas, więc dla zakresu 1 - 10 powinno byćSELECT floor(random() * 10 + 1);
SergiyKolesnikov
9

Jeśli używasz programu SQL Server, prawidłowym sposobem uzyskania liczby całkowitej jest

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

Gdzie

  • „b” to górna granica
  • „a” to dolna granica
Neha Jain
źródło
Uważaj tutaj, jeśli ustawisz dolną granicę na 1, a górną na 10, otrzymasz tylko liczby 1-> 9. Inne odpowiedzi wydają się zakładać, że od 1 do 10 oznacza 1-> 9 ... Sugerowałbym, że jeśli „pomiędzy” wyklucza górną granicę, powinno również wykluczać dolną (tj. 2-> 9). SELECT Cast (RAND () * ((b + 1) -a) + a as int);
Morvael,
Pytanie jest wyraźnie oznaczone jako pytanie PostgreSQL.
Sebastian Palma,
4

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

hythlodayr
źródło
BŁĄD: operator nie istnieje: podwójna precyzja% integer
1
I po co w ogóle miałbyś używać modułu? Ta logika nie ma sensu. Jeśli dostaniesz jakieś „zawijanie”, nie będziesz mieć równej dystrybucji, a jeśli nie dostaniesz żadnego, to nie będziesz go potrzebować.
ErikE,
1

Prawidłowa wersja odpowiedzi hythlodayr.

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

Dane wyjściowe z truncmuszą zostać przekonwertowane na INTEGER. Ale można to zrobić bez trunc. Okazuje się więc, że jest to proste.

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

Generuje wyjście typu INTEGER w zakresie [1, 10], czyli zarówno 1, jak i 10 włącznie.

Dla dowolnej liczby (zmiennoprzecinkowej) zobacz odpowiedź użytkownika80168. tzn. po prostu nie konwertuj go na INTEGER.

mythicalcoder
źródło
0

Właściwie nie wiem, że tego chcesz.

Spróbuj tego

INSERT INTO my_table (my_column)
SELECT
    (random() * 10) + 1
;
leejaycoke
źródło
0

Ta procedura składowana wstawia numer rand do tabeli. Uważaj, wstawia nieskończone liczby. Przestań go wykonywać, gdy uzyskasz wystarczającą liczbę liczb.

utwórz tabelę dla kursora:

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

UDAĆ SIĘ

Utwórz tabelę zawierającą swoje liczby:

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

WSTAWIANIE SKRYPTU:

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

TWORZENIE I WYKONANIE PROCEDURY:

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

Wypełnij swój stół:

EXEC RandNumbers
Abu Khalil Mohamed
źródło
3
Pytanie dotyczy Postgres, a nie SQL Server
a_horse_with_no_name