Ich benötige eine andere Zufallszahl für jede Zeile in meiner Tabelle. Der folgende scheinbar offensichtliche Code verwendet für jede Zeile denselben Zufallswert.
SELECT table_name, RAND() magic_number
FROM information_schema.tables
Ich würde gerne ein INT oder ein FLOAT daraus machen. Der Rest der Geschichte ist, dass ich diese Zufallszahl verwenden werde, um einen zufälligen Datumsversatz von einem bekannten Datum zu erstellen, z. B. 1-14 Tage Versatz von einem Startdatum.
Dies ist für Microsoft SQL Server 2000.
sql-server
tsql
sql-server-2000
MatthewMartin
quelle
quelle
Antworten:
Werfen Sie einen Blick auf SQL Server - Set-basierte Zufallszahlen, die eine sehr detaillierte Erklärung enthalten.
Zusammenfassend erzeugt der folgende Code eine Zufallszahl zwischen 0 und einschließlich 13 mit einer gleichmäßigen Verteilung:
Um Ihren Bereich zu ändern, ändern Sie einfach die Zahl am Ende des Ausdrucks. Seien Sie besonders vorsichtig, wenn Sie einen Bereich benötigen, der sowohl positive als auch negative Zahlen enthält. Wenn Sie es falsch machen, können Sie die Zahl 0 doppelt zählen.
Eine kleine Warnung für die Mathe-Nüsse im Raum: Dieser Code enthält eine sehr leichte Abweichung.
CHECKSUM()
führt zu Zahlen, die über den gesamten Bereich des SQL Int-Datentyps einheitlich sind oder zumindest so nahe, wie meine (der Editor-) Tests zeigen können. Es wird jedoch eine gewisse Verzerrung geben, wenn CHECKSUM () eine Zahl ganz oben in diesem Bereich erzeugt. Jedes Mal, wenn Sie vor dieser maximalen Ganzzahl eine Zahl zwischen der maximal möglichen Ganzzahl und dem letzten exakten Vielfachen der Größe Ihres gewünschten Bereichs (in diesem Fall 14) erhalten, werden diese Ergebnisse gegenüber dem verbleibenden Teil Ihres Bereichs bevorzugt, aus dem nicht erzeugt werden kann das letzte Vielfache von 14.Stellen Sie sich als Beispiel vor, der gesamte Bereich des Int-Typs ist nur 19. 19 ist die größtmögliche Ganzzahl, die Sie halten können. Wenn CHECKSUM () zu 14-19 führt, entsprechen diese den Ergebnissen 0-5. Diese Zahlen würden gegenüber 6-13 stark bevorzugt, da CHECKSUM () sie mit doppelter Wahrscheinlichkeit generiert. Es ist einfacher, dies visuell zu demonstrieren. Nachfolgend finden Sie die gesamte mögliche Ergebnismenge für unseren imaginären ganzzahligen Bereich:
Sie können hier sehen, dass es mehr Chancen gibt, einige Zahlen zu produzieren als andere: Voreingenommenheit. Zum Glück ist der tatsächliche Bereich des Int-Typs viel größer ... so sehr, dass in den meisten Fällen die Vorspannung fast nicht nachweisbar ist. Es ist jedoch etwas zu beachten, wenn Sie dies jemals für einen ernsthaften Sicherheitscode tun.
quelle
Bei mehrmaligem Aufruf in einem Stapel gibt rand () dieselbe Nummer zurück.
Ich würde vorschlagen, convert (
varbinary
,newid()
) als Startargument zu verwenden:newid()
Es wird garantiert, dass bei jedem Aufruf ein anderer Wert zurückgegeben wird, auch innerhalb derselben Charge. Wenn Sie ihn also als Startwert verwenden, wird rand () jedes Mal aufgefordert, einen anderen Wert anzugeben.Bearbeitet, um eine zufällige ganze Zahl von 1 bis 14 zu erhalten.
quelle
Das Obige erzeugt eine (Pseudo-) Zufallszahl zwischen 0 und 1, exklusiv. Bei Verwendung in einer Auswahl wird, da sich der Startwert für jede Zeile ändert, eine neue Zufallszahl für jede Zeile generiert (es wird jedoch nicht garantiert, dass pro Zeile eine eindeutige Nummer generiert wird).
Beispiel in Kombination mit einer Obergrenze von 10 (ergibt die Zahlen 1 - 10):
Transact-SQL-Dokumentation:
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-sqlquelle
Zufallszahlengenerierung zwischen 1000 und 9999 einschließlich:
"+1" - um Obergrenzenwerte einzuschließen (9999 für vorheriges Beispiel)
quelle
FLOOR(RAND(CHECKSUM(NEWID()))*(10000-1000)+1000)
Beantwortung der alten Frage, aber diese Antwort wurde bisher noch nicht gegeben, und hoffentlich ist dies nützlich für jemanden, der diese Ergebnisse über eine Suchmaschine findet.
Mit SQL Server 2008 wurde eine neue Funktion eingeführt,
CRYPT_GEN_RANDOM(8)
die CryptoAPI verwendet, um eine kryptografisch starke Zufallszahl zu erzeugen, die als zurückgegeben wirdVARBINARY(8000)
. Hier ist die Dokumentationsseite: https://docs.microsoft.com/en-us/sql/t-sql/functions/crypt-gen-random-transact-sqlUm eine Zufallszahl zu erhalten, können Sie die Funktion einfach aufrufen und in den erforderlichen Typ umwandeln:
oder um einen
float
Wert zwischen -1 und +1 zu erhalten, können Sie Folgendes tun:quelle
Die Rand () - Funktion generiert dieselbe Zufallszahl, wenn sie in einer Tabellen-SELECT-Abfrage verwendet wird. Gleiches gilt, wenn Sie einen Startwert für die Rand-Funktion verwenden. Eine alternative Möglichkeit besteht darin, Folgendes zu verwenden:
Ich habe die Informationen von hier erhalten , was das Problem sehr gut erklärt.
quelle
Haben Sie in jeder Zeile einen ganzzahligen Wert, den Sie als Startwert an die RAND-Funktion übergeben können?
Um eine ganze Zahl zwischen 1 und 14 zu erhalten, würde dies meiner Meinung nach funktionieren:
quelle
RAND(<seed>)
für geringfügige Änderungen in nicht sehr zufällig zu sein scheint<seed>
. Zum Beispiel einen Schnelltest, den ich gemacht habe: Ich habe<seed>
184380, 184383, 184386 sein lassen, und die entsprechendenRAND(<seed>)
Werte waren: 0,14912, 0,14917, 0,14923.RAND(<seed>)*100000) - FLOOR(RAND(<seed>)*100000)
Wenn Sie Ihren Samen so aufbewahren müssen, dass er jedes Mal die "gleichen" Zufallsdaten generiert, können Sie Folgendes tun:
1. Erstellen Sie eine Ansicht, die select rand () zurückgibt.
2. Erstellen Sie eine UDF, die den Wert aus der Ansicht auswählt.
3. Setzen Sie vor der Auswahl Ihrer Daten die Funktion rand () und verwenden Sie dann die UDF in Ihrer select-Anweisung.
quelle
Versuchen Sie, einen Startwert im RAND (seedInt) zu verwenden. RAND () wird nur einmal pro Anweisung ausgeführt, weshalb Sie jedes Mal dieselbe Nummer sehen.
quelle
RIGHT(CONVERT(BIGINT, RAND(RecNo) * 1000000000000), 2)
(Anmerkung: Ich seheRIGHT
implizit die KonvertierungBIGINT
inCHAR
, aber um streng zu sein, hätten Sie eine andereCONVERT
darin).Wenn Sie nicht benötigen, dass es sich um eine Ganzzahl handelt, sondern um eine zufällige eindeutige Kennung, können Sie diese verwenden
newid()
quelle
Sie müssten RAND () für jede Zeile aufrufen. Hier ist ein gutes Beispiel
https://web.archive.org/web/20090216200320/http://dotnet.org.za/calmyourself/archive/2007/04/13/sql-rand-trap-same-value-per-row.aspx
quelle
RAND()
eine Ansicht ein, fügt eineSELECT
dieser Ansichten in eine Funktion ein und ruft die Funktion dann von überall auf. Klug.Hier liegt die Zufallszahl zwischen 20 und 30. Sie
round
ergibt maximal zwei Dezimalstellen.Wenn Sie negative Zahlen wollen, können Sie es mit tun
Dann ist der minimale Wert -60 und der maximale Wert -50.
quelle
Es ist so einfach wie:
Und dies wird eine Zufallszahl zwischen 0 und 99 in eine Tabelle einfügen:
quelle
Das Problem, das ich manchmal mit der ausgewählten "Antwort" habe, ist, dass die Verteilung nicht immer gleichmäßig ist. Wenn Sie eine sehr gleichmäßige Verteilung der zufälligen 1 - 14 auf viele Zeilen benötigen, können Sie Folgendes tun (meine Datenbank verfügt über 511 Tabellen, sodass dies funktioniert. Wenn Sie weniger Zeilen als die Zufallszahlenspanne haben, funktioniert dies nicht Gut):
Diese Art macht das Gegenteil von normalen Zufallslösungen in dem Sinne, dass die Zahlen sequenziert bleiben und die andere Spalte randomisiert wird.
Denken Sie daran, ich habe 511 Tabellen in meiner Datenbank (was nur relevant ist, wenn wir aus dem Informationsschema auswählen). Wenn ich die vorherige Abfrage in eine temporäre Tabelle #X stelle und diese Abfrage dann für die resultierenden Daten ausführe:
Ich erhalte dieses Ergebnis und zeige, dass meine Zufallszahl SEHR gleichmäßig auf die vielen Zeilen verteilt ist:
quelle
hat immer für mich gearbeitet
quelle
Verwenden Sie newid ()
oder möglicherweise das
quelle
quelle
Versuche dies:
Wo
a
ist die untere Zahl undb
ist die obere Zahlquelle
Nummer zwischen 1 und 10.
quelle