2013-07-01 5 views
1

Я генерирую случайные числа, используя CTE (вместо цикла), используя следующий запрос. Странно, что запрос не генерирует случайные числа после значения Indexer 2. Вы можете посмотреть demo here. Есть ли какие-либо объяснения для этого поведения CTE?Случайные числа SQL Server с использованием CTE

;with LoopCounter 
    as(
     select 1 Indexer, RAND() RandNumber 
     union all 
     select Indexer + 1, RAND() RandNumber 
     from LoopCounter 
     where 
      Indexer <= 1000 
    ) 
    select * 
    from LoopCounter 
    OPTION(MAXRECURSION 0) 
+0

Вы можете добавить Индексатор как семя в RAND(): ... 'выберите Индексатор + 1, RAND (индексатор + 1) RandNumber' ... –

+7

' RAND (СУММА (NEWID ())) 'обеспечит лучшее распределение. Что касается «почему», см. [RAND - постоянная времени выполнения] (http://www.sqlskills.com/blogs/conor/wrapping-my-head-around-rand-in-sql-server/) –

+3

Существует несколько оптимизаций что предотвратит оценку RAND() более одного раза (или в вашем случае, один раз для привязки и один раз для рекурсивной части). Вот идея пресечь это: http://sqlfiddle.com/#!6/72319/4 (это также включает предложение Павла, которое не полагается ни на одну из схем на левой панели). –

ответ

4
;with LoopCounter 
    as(
     select 1 Indexer, ABS(Cast(Cast(CRYPT_GEN_RANDOM(4) as INT) as Float))/Cast(0x7FFFFFFF as int) RandNumber 
     union all 
     select Indexer + 1, ABS(Cast(Cast(CRYPT_GEN_RANDOM(4) as INT) as Float))/Cast(0x7FFFFFFF as int) RandNumber 
     from LoopCounter 
     where 
      Indexer <= 1000 
    ) 
    select * 
    from LoopCounter 
    OPTION(MAXRECURSION 0) 
Смежные вопросы