Potrzebuję innej liczby losowej dla każdego wiersza w mojej tabeli. Poniższy pozornie oczywisty kod używa tej samej losowej wartości dla każdego wiersza.
SELECT table_name, RAND() magic_number
FROM information_schema.tables
Chciałbym uzyskać z tego INT lub FLOAT. Reszta historii polega na tym, że użyję tej losowej liczby do utworzenia losowego przesunięcia daty od znanej daty, np. 1-14 dni przesunięcia od daty początkowej.
Dotyczy to Microsoft SQL Server 2000.
sql-server
tsql
sql-server-2000
MatthewMartin
źródło
źródło
Odpowiedzi:
Spójrz na SQL Server - Ustaw losowe liczby oparte na bardzo szczegółowym objaśnieniu.
Podsumowując, poniższy kod generuje liczbę losową od 0 do 13 włącznie o jednolitym rozkładzie:
Aby zmienić zakres, wystarczy zmienić liczbę na końcu wyrażenia. Zachowaj szczególną ostrożność, jeśli potrzebujesz zakresu obejmującego zarówno liczby dodatnie, jak i ujemne. Jeśli zrobisz to źle, możliwe jest podwójne policzenie liczby 0.
Małe ostrzeżenie dla orzechów matematycznych w pokoju: w tym kodzie jest bardzo niewielki błąd.
CHECKSUM()
skutkuje liczbami, które są jednolite w całym zakresie typu danych sql Int lub przynajmniej tak blisko, jak może pokazać moje (edytor) testowanie. Jednak wystąpi pewne odchylenie, gdy CHECKSUM () wygeneruje liczbę na samym górnym końcu tego zakresu. Za każdym razem, gdy pojawi się liczba między maksymalną możliwą liczbą całkowitą a ostatnią dokładną wielokrotnością rozmiaru pożądanego zakresu (w tym przypadku 14) przed tymi liczbami całkowitymi, wyniki te są uprzywilejowane w stosunku do pozostałej części zakresu, z której nie można uzyskać ostatnia wielokrotność 14.Jako przykład wyobraź sobie, że cały zakres typu Int wynosi tylko 19. 19 to największa możliwa liczba całkowita, jaką możesz pomieścić. Kiedy CHECKSUM () daje wynik 14-19, odpowiadają one wynikom 0-5. Liczby te byłyby znacznie bardziej uprzywilejowane w zakresie 6-13, ponieważ CHECKSUM () ma dwa razy większe szanse na ich wygenerowanie. Łatwiej jest to zademonstrować wizualnie. Poniżej znajduje się cały możliwy zestaw wyników dla naszego wyimaginowanego zakresu liczb całkowitych:
Widać tutaj, że istnieje większa szansa na uzyskanie niektórych liczb niż innych: stronniczości. Na szczęście rzeczywisty zasięg typu Int jest znacznie większy ... tak bardzo, że w większości przypadków odchylenie jest prawie niewykrywalne. Należy jednak pamiętać, jeśli robisz to z poważnym kodem bezpieczeństwa.
źródło
Gdy wywoływany wiele razy w jednej partii, rand () zwraca ten sam numer.
Sugerowałbym użycie argumentu konwersji (
varbinary
,newid()
) jako argumentu źródłowego:newid()
gwarantuje, że zwróci inną wartość za każdym razem, gdy zostanie wywołane, nawet w tej samej partii, więc użycie go jako zarodka spowoduje, że rand () poda za każdym razem inną wartość.Edytowano, aby uzyskać losową liczbę całkowitą od 1 do 14.
źródło
Powyższe wygeneruje (pseudo-) losową liczbę od 0 do 1, z wyłączeniem. Jeśli zostanie użyty w selekcji, ponieważ wartość nasion zmienia się dla każdego wiersza, wygeneruje on nową liczbę losową dla każdego wiersza (nie ma jednak gwarancji, że wygeneruje unikalną liczbę dla wiersza).
Przykład w połączeniu z górną granicą 10 (daje liczby 1–10):
Dokumentacja Transact-SQL:
CAST()
: https://docs.microsoft.com/en-us/sql/t-sql/functions/cast-and-convert-transact-sqlRAND()
: http://msdn.microsoft.com/en-us/library/ms177610.aspxCHECKSUM()
: http://msdn.microsoft.com/en-us/library/ms189788.aspxNEWID()
: https://docs.microsoft.com/en-us/sql/t-sql/functions/newid-transact-sqlźródło
Generowanie liczb losowych od 1000 do 9999 włącznie:
„+1” - aby uwzględnić górne wartości graniczne (9999 w poprzednim przykładzie)
źródło
FLOOR(RAND(CHECKSUM(NEWID()))*(10000-1000)+1000)
Odpowiadając na stare pytanie, ale ta odpowiedź nie została wcześniej podana, i mam nadzieję, że przyda się to komuś, kto znajdzie te wyniki za pośrednictwem wyszukiwarki.
W SQL Server 2008 wprowadzono nową funkcję
CRYPT_GEN_RANDOM(8)
, która wykorzystuje CryptoAPI do stworzenia kryptograficznie silnej liczby losowej zwracanej jakoVARBINARY(8000)
. Oto strona dokumentacji: https://docs.microsoft.com/en-us/sql/t-sql/functions/crypt-gen-random-transact-sqlAby uzyskać losowy numer, możesz po prostu wywołać funkcję i przypisać ją do odpowiedniego typu:
lub aby uzyskać
float
od -1 do +1, możesz zrobić coś takiego:źródło
Funkcja Rand () wygeneruje tę samą liczbę losową, jeśli zostanie użyta w zapytaniu SELECT tabeli. To samo dotyczy, jeśli użyjesz nasionka do funkcji Rand. Alternatywnym sposobem na to jest użycie tego:
Mam tutaj informacje , które bardzo dobrze wyjaśniają problem.
źródło
Czy masz wartość całkowitą w każdym wierszu, którą możesz przekazać jako ziarno do funkcji RAND?
Aby uzyskać liczbę całkowitą od 1 do 14, myślę, że to zadziała:
źródło
RAND(<seed>)
że nie wydaje się to zbyt przypadkowe w przypadku drobnych zmian w<seed>
. Na przykład zrobiłem szybki test: pozwoliłem<seed>
być 184380, 184383, 184386, a odpowiednieRAND(<seed>)
wartości to: 0,14912, 0,14917, 0,14923.RAND(<seed>)*100000) - FLOOR(RAND(<seed>)*100000)
Jeśli chcesz zachować ziarno, aby za każdym razem generowało „te same” losowe dane, możesz wykonać następujące czynności:
1. Utwórz widok, który zwraca select rand ()
2. Utwórz UDF, który wybiera wartość z widoku.
3. Przed wybraniem danych uruchom funkcję rand (), a następnie użyj UDF w instrukcji select.
źródło
spróbuj użyć wartości początkowej w RAND (seedInt). Funkcja RAND () będzie wykonywana tylko raz na instrukcję, dlatego za każdym razem widzisz tę samą liczbę.
źródło
RIGHT(CONVERT(BIGINT, RAND(RecNo) * 1000000000000), 2)
(Uwaga: WidzęRIGHT
niejawnie przekonwertowaćBIGINT
doCHAR
, ale być rygorystyczne, że masz innyCONVERT
tam).Jeśli nie potrzebujesz, aby była liczbą całkowitą, ale dowolnym losowym unikalnym identyfikatorem, możesz użyć
newid()
źródło
Musisz wywołać RAND () dla każdego wiersza. Oto dobry przykład
https://web.archive.org/web/20090216200320/http://dotnet.org.za/calmyourself/archive/2007/04/13/sql-rand-trap-same-value-per-row.aspx
źródło
RAND()
widok, umieszczaSELECT
widok tego widoku w funkcji, a następnie wywołuje funkcję z dowolnego miejsca. Sprytny.Tutaj liczba losowa
round
będzie zawierać się między 20 a 30. da maksymalnie dwa miejsca po przecinku.Jeśli chcesz liczb ujemnych, możesz to zrobić
Wtedy minimalna wartość wyniesie -60, a maksymalna wyniesie -50.
źródło
To tak proste jak:
A to umieści losową liczbę od 0 do 99 w tabeli:
źródło
Problem, który czasami mam z wybraną odpowiedzią, polega na tym, że dystrybucja nie zawsze jest równa. Jeśli potrzebujesz bardzo równomiernego rozkładu losowego 1 - 14 między wiele wierszy, możesz zrobić coś takiego (moja baza danych ma 511 tabel, więc to działa. Jeśli masz mniej wierszy niż przedział liczb losowych, to nie działa dobrze):
Ten rodzaj działa odwrotnie niż normalne losowe rozwiązania w tym sensie, że utrzymuje sekwencję liczb i losuje drugą kolumnę.
Pamiętaj, że mam 511 tabel w mojej bazie danych (co jest istotne tylko b / c wybieramy z schematu_informacji). Jeśli wezmę poprzednie zapytanie i umieszczę je w tabeli tymczasowej #X, a następnie uruchomię to zapytanie na wynikowych danych:
Otrzymuję ten wynik, pokazując mi, że moja losowa liczba jest BARDZO równomiernie rozmieszczona w wielu wierszach:
źródło
zawsze dla mnie pracował
źródło
Użyj newid ()
a może to
źródło
źródło
Spróbuj tego:
Gdzie
a
jest niższa liczba ib
wyższa liczbaźródło
Liczba od 1 do 10.
źródło