Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Случайное распределения с неповторающимися значениями  [new]
хмхм
Guest
Уважаемые участники форума, помогите пожалуйста советом.

Возможно ли избежать использование цикла в моем примере?
Пример:
Надо получить распределенные случайным образом 6ть значений в диапазоне от 0 до 10.
Сделал такой запрос:

		declare @ratio decimal(18,2) = 2147483647.0/10
				,@cardinality int = 6
  
		;with  s(step, qty)
		as (
			select
			   abs(cast(cast(cast(newid() as varbinary(16)) as integer)/@ratio as integer)), 1 as qty
			union all
			select
			   abs(cast(cast(cast(newid() as varbinary(16)) as integer)/@ratio as integer)), qty + 1
			from
			   s
			where
			   qty < @cardinality
			)
   select * from s
   order by
	  step
	option
		  (maxrecursion 0);


Запрос иногда возвращает повторяющиеся значения, от которых надо избавиться.
Теоретически я могу записать неповторяющиеся результаты во временную таблицу (например используя
select distinct
), а затем сравнить количество в этой временной таблице и то количество которое мне надо получить, если не совпадет, то вызвать заново. Но мне кажется есть вариант получше. Может быть кто-то подскажет как сделать лучше и оптимальнее.

select @@version
Microsoft SQL Server 2012 - 11.0.2100.60 (X64) 
9 сен 13, 18:18    [14815791]     Ответить | Цитировать Сообщить модератору
 Re: Случайное распределения с неповторающимися значениями  [new]
Гость333
Member

Откуда:
Сообщений: 3683
with numbers (n) as
(  select 0 union all select 1 union all select 2 union all select 3 union all select 4 union all
   select 5 union all select 6 union all select 7 union all select 8 union all select 9 union all select 10
)
select top (6) n
from numbers
order by newid()
9 сен 13, 18:42    [14815907]     Ответить | Цитировать Сообщить модератору
 Re: Случайное распределения с неповторающимися значениями  [new]
iap
Member

Откуда: Москва
Сообщений: 47145
Гость333
with numbers (n) as
(  select 0 union all select 1 union all select 2 union all select 3 union all select 4 union all
   select 5 union all select 6 union all select 7 union all select 8 union all select 9 union all select 10
)
select top (6) n
from numbers
order by newid()
SELECT TOP(6) n FROM(VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9),(10))T(n) ORDER BY NEWID();
Запись немного короче получается
9 сен 13, 19:55    [14816272]     Ответить | Цитировать Сообщить модератору
 Re: Случайное распределения с неповторающимися значениями  [new]
Гость333
Member

Откуда:
Сообщений: 3683
iap
Гость333
with numbers (n) as
(  select 0 union all select 1 union all select 2 union all select 3 union all select 4 union all
   select 5 union all select 6 union all select 7 union all select 8 union all select 9 union all select 10
)
select top (6) n
from numbers
order by newid()
SELECT TOP(6) n FROM(VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9),(10))T(n) ORDER BY NEWID();
Запись немного короче получается

Да у меня дурацкая привычка писать так, чтобы выполнялось и под mssql 2005 :-)
9 сен 13, 20:04    [14816294]     Ответить | Цитировать Сообщить модератору
 Re: Случайное распределения с неповторающимися значениями  [new]
StarikNavy
Member

Откуда: Москва
Сообщений: 2415
Гость333
Да у меня дурацкая привычка писать так, чтобы выполнялось и под mssql 2005 :-)


говорят, что водители автобуса, даже когда едут на личной машине, все равно притормаживают возле каждой остановки ;)
10 сен 13, 09:25    [14817812]     Ответить | Цитировать Сообщить модератору
 Re: Случайное распределения с неповторающимися значениями  [new]
хмхм
Guest
Гость333,

хорошая идея, спасибо. А если номеров столько, сколько содержится в типе integer? Вернее от 0 до 2147483647? Заводить отдельную таблицу?
10 сен 13, 10:09    [14818073]     Ответить | Цитировать Сообщить модератору
 Re: Случайное распределения с неповторающимися значениями  [new]
Гость333
Member

Откуда:
Сообщений: 3683
хмхм
А если номеров столько, сколько содержится в типе integer? Вернее от 0 до 2147483647?

Как-то так?
set nocount on;

declare @random table (a int primary key with(ignore_dup_key = on), id int identity);

declare @cardinality int;

set @cardinality = 6;

while (select count(*) from @random) < @cardinality
   insert @random(a)
   values(rand() * 2147483648);

   
select * from @random order by id;

Вы лучше сразу всю задачу огласите ;-)
10 сен 13, 10:21    [14818128]     Ответить | Цитировать Сообщить модератору
 Re: Случайное распределения с неповторающимися значениями  [new]
iap
Member

Откуда: Москва
Сообщений: 47145
SELECT
 N1=CAST(2147483647*RAND(CHECKSUM(NEWID()))AS INT)
,N2=CAST(2147483647*RAND(CHECKSUM(NEWID()))AS INT)
,N3=CAST(2147483647*RAND(CHECKSUM(NEWID()))AS INT);
10 сен 13, 22:14    [14822884]     Ответить | Цитировать Сообщить модератору
 Re: Случайное распределения с неповторающимися значениями  [new]
iap
Member

Откуда: Москва
Сообщений: 47145
iap
SELECT
 N1=CAST(2147483647*RAND(CHECKSUM(NEWID()))AS INT)
,N2=CAST(2147483647*RAND(CHECKSUM(NEWID()))AS INT)
,N3=CAST(2147483647*RAND(CHECKSUM(NEWID()))AS INT);
Только нет гарантии, что эти три числа будут не равны друг другу...
10 сен 13, 22:16    [14822893]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить