2013-07-01 2 views
1

아래의 쿼리를 사용하여 CTE (루프 대신)를 사용하여 난수를 생성합니다. 이상한 점은 인덱서 값 2 이후에 쿼리가 임의의 숫자를 생성하지 않는다는 것입니다. demo here을 볼 수 있습니다. CTE의 행동에 대한 설명이 있습니까?CTE를 사용하는 SQL Server 난수

;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 (CHECKSUM (NEWID ()))'이 더 나은 배포를 제공 할 것입니다. '왜'에 관해서는 [RAND는 런타임 상수입니다.] (http://www.sqlskills.com/blogs/conor/wrapping-my-head-around-rand-in-sql-server/)를 참조하십시오. –

+3

여러 최적화가 있습니다. RAND()가 두 번 이상 평가되는 것을 방지합니다 (또는 앵커의 경우 한 번, 재귀 부분의 경우 한 번). http://sqlfiddle.com/#!6/72319/4 (왼쪽 창에있는 스키마에 의존하지 않는 Paul의 제안이 포함되어 있습니다)을 방해하는 아이디어가 있습니다. –

답변

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) 
관련 문제