Gere um número aleatório no intervalo de 1 a 10

95

Como minha abordagem para uma consulta de teste na qual trabalhei nesta questão não funcionou, estou tentando outra coisa agora. Existe uma maneira de dizer à random()função da página para obter apenas números entre 1 e 10?

KB22
fonte

Respostas:

152

Se por números entre 1 e 10 você quer dizer qualquer float> = 1 e <10, então é fácil:

select random() * 9 + 1

Isso pode ser facilmente testado com:

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

Se você quiser números inteiros, que são> = 1 e <10, é simples:

select trunc(random() * 9 + 1)

E novamente, teste simples:

# 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
fonte
selecione a data (e.created_at) + (trunc (random () * 20)) dos eventos e; resulta em: ERROR: operador does not exist: date + double precision O trunc realmente retorna inteiros?
Bogdan Gusiev
3
trunc()retorna o mesmo tipo de dados da entrada (conforme declarado no manual). Você precisa converter o resultado para um inteiro:trunc(random() * 20)::int
a_horse_with_no_name
Eu me pergunto se pelo menos em teoria seria possível que random()retornasse um valor <1 que quando multiplicado por 9 seria> = 9 devido à natureza inexata do tipo de precisão dupla ? Na prática, mesmo que fosse possível, seria extremamente improvável, é claro, por causa da precisão de 15 dígitos ou mais.
1
Estou brincando com width_bucket(random(), 0, 1, 10)uma alternativa
Parece que meus medos eram infundados, embora eu confesse que não entendo a matemática :-)
17

Para resumir e simplificar um pouco, você pode usar:

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

E você pode testar isso como mencionado por @ 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
fonte
2
Os documentos dizem "valor aleatório no intervalo 0,0 <= x <1,0", então há pelo menos uma chance teórica de ceil(random() * 10)resultar em 0 - eu ficaria com floor.
1
Eu concordo com @JackDouglas, então para o intervalo de 1 a 10 deveria serSELECT floor(random() * 10 + 1);
SergiyKolesnikov
9

Se você estiver usando o SQL Server, a maneira correta de obter o inteiro é

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

Onde

  • 'b' é o limite superior
  • 'a' é o limite inferior
Neha Jain
fonte
Tenha cuidado aqui, se você colocar seu limite inferior como 1 e superior como 10, você obterá apenas números 1-> 9. Outras respostas parecem assumir que entre 1 e 10 significa 1-> 9 ... Eu sugeriria que se 'entre' exclui o limite superior, também deve excluir o inferior (ou seja, 2-> 9). SELECT Cast (RAND () * ((b + 1) -a) + a como int);
Morvael
A questão está claramente marcada como uma questão PostgreSQL.
Sebastian Palma
4

(trunc (aleatório () * 10)% 10) + 1

hythlodayr
fonte
ERRO: o operador não existe: precisão dupla% inteiro
1
E por que você usaria módulo de qualquer maneira? Essa lógica não faz sentido. Se você receber qualquer "embalagem", não terá distribuição igual e, se não receber, não precisará dela.
ErikE
1

A versão correta da resposta de hythlodayr.

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

A saída de truncdeve ser convertida em INTEGER. Mas isso pode ser feito sem trunc. Portanto, é simples.

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

Gera uma saída INTEGER no intervalo [1, 10], ou seja, 1 e 10 inclusive.

Para qualquer número (flutuantes), consulte a resposta do usuário80168. ou seja, apenas não converta para INTEGER.

codificador mítico
fonte
0

Na verdade, não sei se você quer isso.

tente isso

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

Este procedimento armazenado insere um número rand em uma tabela. Cuidado, ele insere uma infinidade de números. Pare de executá-lo quando obter números suficientes.

crie uma tabela para o cursor:

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

IR

Crie uma tabela para conter seus números:

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

INSERINDO O SCRIPT:

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

CRIANDO E EXECUTANDO O PROCEDIMENTO:

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

Encha a sua mesa:

EXEC RandNumbers
Abu Khalil Mohamed
fonte
3
A pergunta é sobre Postgres, não SQL Server
a_horse_with_no_name