Preciso de um número aleatório diferente para cada linha da minha tabela. O código aparentemente óbvio a seguir usa o mesmo valor aleatório para cada linha.
SELECT table_name, RAND() magic_number
FROM information_schema.tables
Eu gostaria de obter um INT ou um FLOAT com isso. O resto da história é que vou usar esse número aleatório para criar um deslocamento aleatório de data a partir de uma data conhecida, por exemplo, um deslocamento de 1 a 14 dias a partir de uma data inicial.
Isso é para o Microsoft SQL Server 2000.
sql-server
tsql
sql-server-2000
MatthewMartin
fonte
fonte
Respostas:
Dê uma olhada no SQL Server - Defina números aleatórios baseados em uma explicação muito detalhada.
Para resumir, o código a seguir gera um número aleatório entre 0 e 13, inclusive com uma distribuição uniforme:
Para alterar seu intervalo, basta alterar o número no final da expressão. Tenha muito cuidado se precisar de um intervalo que inclua números positivos e negativos. Se você errar, é possível contar duas vezes o número 0.
Um pequeno aviso para as porcas matemáticas da sala: há um pequeno viés nesse código.
CHECKSUM()
resulta em números uniformes em todo o intervalo do tipo de dados sql Int, ou pelo menos o mais próximo possível para o meu teste (do editor). No entanto, haverá algum viés quando CHECKSUM () produzir um número na extremidade superior desse intervalo. Sempre que você obtém um número entre o número máximo máximo possível e o último múltiplo exato exato do tamanho do intervalo desejado (14 neste caso) antes desse número máximo máximo, esses resultados são favorecidos sobre a parte restante do intervalo que não pode ser produzida a partir de esse último múltiplo de 14.Como um exemplo, imagine que todo o intervalo do tipo Int seja apenas 19. 19 é o maior número possível possível. Quando CHECKSUM () resulta em 14-19, eles correspondem aos resultados 0-5. Esses números seriam altamente favorecidos entre 6-13, porque CHECKSUM () tem duas vezes mais chances de gerá-los. É mais fácil demonstrar isso visualmente. Abaixo está todo o conjunto possível de resultados para o nosso intervalo inteiro imaginário:
Você pode ver aqui que há mais chances de produzir alguns números do que outros: viés. Felizmente, o alcance real do tipo Int é muito maior ... tanto que, na maioria dos casos, o viés é quase indetectável. No entanto, é algo a ter em atenção se você se encontra fazendo isso por um código de segurança sério.
fonte
Quando chamado várias vezes em um único lote, rand () retorna o mesmo número.
Eu sugiro usar convert (
varbinary
,newid()
) como o argumento de semente:newid()
é garantido que retorne um valor diferente cada vez que for chamado, mesmo dentro do mesmo lote, portanto, usá-lo como uma semente solicitará que rand () forneça um valor diferente a cada vez.Editado para obter um número inteiro aleatório de 1 a 14.
fonte
O acima irá gerar um número (pseudo-) aleatório entre 0 e 1, exclusivo. Se usado em uma seleção, porque o valor inicial muda para cada linha, ele gerará um novo número aleatório para cada linha (não é garantido que você gere um número único por linha).
Exemplo quando combinado com um limite superior de 10 (produz os números 1 - 10):
Documentação Transact-SQL:
CAST()
: https://docs.microsoft.com/en-us/sql/t-sql/functions/cast-and-convert-transact-sqlRAND()
: http://msdn.microsoft.com/en-us/library/ms177610.aspxCHECKSUM()
: http://msdn.microsoft.com/en-us/library/ms189788.aspxNEWID()
: https://docs.microsoft.com/en-us/sql/t-sql/functions/newid-transact-sqlfonte
Geração aleatória de números entre 1000 e 9999, inclusive:
"+1" - para incluir valores do limite superior (9999 no exemplo anterior)
fonte
FLOOR(RAND(CHECKSUM(NEWID()))*(10000-1000)+1000)
Respondendo à pergunta antiga, mas essa resposta não foi fornecida anteriormente, e espero que seja útil para alguém encontrar esses resultados por meio de um mecanismo de pesquisa.
Com o SQL Server 2008, uma nova função foi introduzida
CRYPT_GEN_RANDOM(8)
, que usa o CryptoAPI para produzir um número aleatório criptograficamente forte, retornado comoVARBINARY(8000)
. Aqui está a página da documentação: https://docs.microsoft.com/en-us/sql/t-sql/functions/crypt-gen-random-transact-sqlPortanto, para obter um número aleatório, você pode simplesmente chamar a função e convertê-la no tipo necessário:
ou para obter um valor
float
entre -1 e +1, você pode fazer algo assim:fonte
A função Rand () gerará o mesmo número aleatório, se usada em uma consulta SELECT da tabela. O mesmo se aplica se você usar uma semente na função Rand. Uma maneira alternativa de fazer isso é usar o seguinte:
Consegui as informações aqui , o que explica muito bem o problema.
fonte
Você tem um valor inteiro em cada linha que pode passar como uma semente para a função RAND?
Para obter um número inteiro entre 1 e 14, acredito que isso funcionaria:
fonte
RAND(<seed>)
que não parece ser muito aleatório para pequenas alterações<seed>
. Por exemplo, um teste rápido que fiz: deixei<seed>
ser 184380, 184383, 184386 e osRAND(<seed>)
valores correspondentes foram: 0,14912, 0,14917, 0,14923.RAND(<seed>)*100000) - FLOOR(RAND(<seed>)*100000)
Se você precisar preservar sua semente para que ela gere os mesmos dados aleatórios todas as vezes, faça o seguinte:
1. Crie uma exibição que retorne select rand ()
2. Crie um UDF que selecione o valor na visualização.
3. Antes de selecionar seus dados, propague a função rand () e use o UDF na sua instrução select.
fonte
tente usar um valor inicial no RAND (seedInt). RAND () será executado apenas uma vez por instrução, e é por isso que você vê o mesmo número cada vez.
fonte
RIGHT(CONVERT(BIGINT, RAND(RecNo) * 1000000000000), 2)
(nota: estou vendoRIGHT
implicitamente converter oBIGINT
paraCHAR
, mas para ser rigoroso, você terá outroCONVERT
).Se você não precisar que ele seja um número inteiro, mas qualquer identificador exclusivo aleatório, poderá usar
newid()
fonte
Você precisaria chamar RAND () para cada linha. Aqui está um bom exemplo
https://web.archive.org/web/20090216200320/http://dotnet.org.za/calmyourself/archive/2007/04/13/sql-rand-trap-same-value-per-row.aspx
fonte
RAND()
uma visão, coloca umaSELECT
dessa visão em uma função e depois a chama de qualquer lugar. Inteligente.Aqui o número aleatório estará entre 20 e 30.
round
dará duas casas decimais no máximo.Se você quer números negativos, pode fazê-lo com
Então o valor mínimo será -60 e max será -50.
fonte
É tão fácil quanto:
E isso colocará um número aleatório entre 0-99 em uma tabela:
fonte
O problema que às vezes tenho com a "Resposta" selecionada é que a distribuição nem sempre é uniforme. Se você precisar de uma distribuição muito uniforme de 1 a 14 aleatórios entre várias linhas, poderá fazer algo assim (meu banco de dados possui 511 tabelas, portanto isso funcionará. Se você tiver menos linhas do que o intervalo de números aleatórios, isso não funcionará) bem):
Isso meio que faz o oposto das soluções aleatórias normais, no sentido de manter os números sequenciados e randomizar a outra coluna.
Lembre-se, eu tenho 511 tabelas no meu banco de dados (que é pertinente apenas porque estamos selecionando no information_schema). Se eu pegar a consulta anterior e colocá-la em uma tabela temporária #X e executar essa consulta nos dados resultantes:
Eu recebo esse resultado, mostrando-me que meu número aleatório é MUITO distribuído igualmente entre as muitas linhas:
fonte
sempre trabalhou para mim
fonte
Use newid ()
ou possivelmente isso
fonte
fonte
Tente o seguinte:
Onde
a
é o número mais baixo eb
é o número superiorfonte
Número entre 1 e 10.
fonte