Pergunta

Estou executando uma consulta SQL no SQL Server 2005, e, além de 2 colunas sendo consultado a partir do banco de dados, eu também gostaria de retornar 1 coluna de números aleatórios junto com eles. Eu tentei isso:

select column1, column2, floor(rand() * 10000) as column3 
from table1

Que funciona um bocado, mas o problema é que esta consulta retorna o mesmo número aleatório em cada linha. É um número diferente a cada vez que você executar a consulta, mas não variam de linha para linha. Como posso fazer isso e obter um novo número aleatório para cada linha?

Foi útil?

Solução

Sei que este é um cargo mais velho ... mas você não precisa de um ponto de vista.

select column1, column2, 
  ABS(CAST(CAST(NEWID() AS VARBINARY) AS int)) % 10000 as column3 
from table1

Outras dicas

AVISO

a resposta de Adam envolvendo a vista é muito ineficiente e para grandes conjuntos podem tirar o seu banco de dados por um bom tempo, eu recomendo fortemente contra a usá-lo em uma base regular ou em situações em que você precisa para preencher tabelas grandes em Produção.

Em vez disso, você poderia usar esta resposta .

Proof:

CREATE VIEW vRandNumber
AS
SELECT RAND() as RandNumber

go 

CREATE FUNCTION RandNumber()
RETURNS float
AS
  BEGIN
  RETURN (SELECT RandNumber FROM vRandNumber)
  END

go 

create table bigtable(i int)

go 

insert into bigtable 
select top 100000 1 from sysobjects  a
join sysobjects b on 1=1

go 

select cast(dbo.RandNumber() * 10000 as integer) as r into #t from bigtable 
-- CPU (1607) READS (204639) DURATION (1551)

go

select ABS(CAST(CAST(NEWID() AS VARBINARY) AS int)) % 10000 as r  into #t1 
from bigtable
-- Runs 15 times faster - CPU (78) READS (809) DURATION (99)

Profiler rastreamento:

alt texto http://img519.imageshack.us/img519/8425/destroydbxu9 .png

Esta é a prova de que o material é suficiente aleatório para números entre 0 a 9999

-- proof that stuff is random enough 
select avg(r) from #t
-- 5004
select STDEV(r) from #t
-- 2895.1999 

select avg(r) from #t1
-- 4992
select STDEV(r) from #t1
-- 2881.44 


select r,count(r) from #t
group by r 
-- 10000 rows returned 

select r,count(r) from #t1
group by r 
-- 10000 row returned 

A resposta de Adam funciona muito bem, então eu marcado como aceito. Enquanto eu estava esperando por uma resposta, porém, eu também encontrei este blog com alguns outros métodos (um pouco menos aleatórios). O método de Kaboing estava entre eles.

http: / /blog.sqlauthority.com/2007/04/29/sql-server-random-number-generator-script-sql-query/

select RAND(CHECKSUM(NEWID()))

Você precisa usar uma UDF

primeira:

CREATE VIEW vRandNumber
AS
SELECT RAND() as RandNumber

segundo:

CREATE FUNCTION RandNumber()
RETURNS float
AS
  BEGIN
  RETURN (SELECT RandNumber FROM vRandNumber)
  END

teste:

SELECT dbo.RandNumber(), *
FROM <table>

Acima emprestado de Jeff SQL Server Blog

Para SQLServer, há um par de opções.
1. Um tempo loop para actualizar uma coluna vazia com um número aleatório de cada vez
2. um .NET assembly que contém uma função que retorna um número aleatório

Você pode querer considerar gerando um UUID em vez de um número aleatório usando a função newid. Estes são garantidos para ser único a cada vez gerado Considerando que há uma chance significativa de que alguma duplicação irá ocorrer com um número aleatório simples (e dependendo do que você está usando para isso poderia lhe dar uma phenominally difícil de erro de depuração em um momento posterior)

newid () eu acredito é muito recurso intensivo. Lembro-me de tentar esse método em uma mesa de alguns milhões de registros e o desempenho não foi tão bom quanto rand ().

De acordo com meus testes, a resposta acima não gera um valor de 10000 nunca. Isso provavelmente não é muito de um problema quando você está gerando um aleatório entre 1 e 10000, mas o mesmo algoritmo entre 1 e 5 seria perceptível. Adicione 1 à sua modificação.

Este trecho parece fornecer um substituto razoável para rand() em que ele retorna um float entre 0,0 e 1,0. Ele usa apenas os últimos 3 bytes fornecidos pelo newid() tão aleatoriedade total pode ser ligeiramente diferente do que a conversão para VARBINARY então INT então modding da resposta recomendada. Não têm tido a oportunidade de testar o desempenho relativo, mas parece bastante rápido (e bastante aleatório) para os meus propósitos.

SELECT CAST(SubString(CONVERT(binary(16), newid()), 14, 3) AS INT) / 16777216.0 AS R

Eu uso c # para lidar com números aleatórios. É muito mais limpo. Eu tenho uma função que eu uso para retornar uma lista de números aleatórios e uma chave única, então eu simplesmente aderem ao uniqueKey no número da linha. Porque eu usar c #, eu posso facilmente especificar um intervalo dentro do qual os números aleatórios deve cair.

Aqui estão os passos para fazer a função: http://www.sqlwithcindy.com /2013/04/elegant-random-number-list-in-sql-server.html

Aqui está o que meus fins de consulta acima de olhar como:

SELECT 
   rowNumber, 
   name, 
   randomNumber
FROM dbo.tvfRandomNumberList(1,10,100) 
INNER JOIN (select ROW_NUMBER() over (order by int_id) as 'rowNumber', name from client        
            )as clients
ON clients.rowNumber = uniqueKey

Consulta

select column1, column2, cast(new_id() as varchar(10)) as column3 
from table1
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top