2010-09-22 14 views
5

Chcę losowo wybrać wartość z małego zakresu liczb całkowitych (mniej niż 200). Jako alternatywę dlaCRYPT_GEN_RANDOM dziwne efekty

SELECT RAND() 

Próbuję użyć

CAST(CAST(CRYPT_GEN_RANDOM(2) AS INTEGER) AS FLOAT)/65535 

ale Dostaję jakieś dziwne efekty.

Na przykład:

WITH Numbers (num) 
    AS 
    (
     SELECT num 
     FROM (
       VALUES (1), (2), (3), (4), 
        (5), (6), (7), (8), 
        (9), (10) 
      ) AS Numbers (num) 
    ), 
    RandomNumber (num) 
    AS 
    (
     SELECT CAST(
        (CAST(CAST(CRYPT_GEN_RANDOM(2) AS INTEGER) AS FLOAT)/65535) 
        * (SELECT COUNT(*) FROM Numbers) + 1 
        AS INTEGER 
       ) 
    ) 
SELECT T1.num, R1.num 
    FROM Numbers AS T1 
     INNER JOIN RandomNumber AS R1 
      ON T1.num = R1.num; 

będę oczekiwać tego, aby powrócić dokładnie jeden wiersz z obu wartości kolumn równych.

Jednakże zwraca zero, jeden lub więcej wierszy, przy czym wartości kolumn są tylko czasami równe.

Masz pojęcie, co się tutaj dzieje?

+0

Zmień nazwę jako kota Schrödingera lub zasadę niepewności na serwerze Sql! hahah –

+0

[Blogged about this here] (http://sqlperformance.com/2014/06/t-sql-queries/dirty-secrets-of-the-case-expression). –

Odpowiedz

8

Spróbuj tego:

select abs(checksum(newid()))%200 

Aktualizacja

coś podejrzanego się dzieje tutaj:

select 'Not in the range! This is impossible!' [Message] 
where cast(CAST(CAST(CRYPT_GEN_RANDOM(2) AS int) AS float)/65535 * 10 as int) 
not in (0,1,2,3,4,5,6,7,8,9) 

Hit F5 aż pojawi się komunikat.

Aktualizacja 2

Zapytanie ma ten sam efekt:

select 'Not in the range! This is impossible!' [Message] 
where abs(checksum(newid()))%10 
not in (0,1,2,3,4,5,6,7,8,9) 

aktualizacji 3

select N'WTF? Schrödinger''s cat!' [Message], * 
from (select 0 union select 1) t(n) 
join (select abs(checksum(newid()))%2 rnd) r(n) on t.n = r.n 

i ten ostatni zapytanie może czasami powrócić 2 rzędy co zasadniczo oznacza, że abs(checksum(newid()))%2 zwraca 0 i 1 w tym samym czasie co impossi ble, ponieważ jest zawarty w instrukcji "select one only only", stąd wartość jest aktualizowana później po dokonaniu sprzężenia. : | A potem znowu następuje sprzężenie, które jest oszołomieniem.

Aktualizacja 4

Jest a known bug w Microsoft Connect. I tutaj jest an insightful article o tym, co się dzieje.

+0

Dzięki za alternatywę, jestem pewien, że jest ich więcej. Ale czy możesz wyjaśnić dziwne efekty * mojego * kodu? – onedaywhen

+0

Może OP ma dobry powód, by potrzebować liczby losowej o krypto jakości. – LukeH

+0

@staywhen @LukeH Widzę ... –