UPDATE CattleProds
SET SheepTherapy=(ROUND((RAND()* 10000),0))
WHERE SheepTherapy IS NULL
Wenn ich dann SELECT mache, sehe ich, dass meine Zufallszahl in jeder Zeile identisch ist . Irgendwelche Ideen, wie man eindeutige Zufallszahlen generiert?
sql-server
NibblyPig
quelle
quelle
Wenn Sie mit SQL Server 2008 arbeiten, können Sie auch verwenden
Was etwas einfacher erscheint (es wird auch einmal pro Zeile ausgewertet, wie
newid
es unten gezeigt wird)DECLARE @foo TABLE (col1 FLOAT) INSERT INTO @foo SELECT 1 UNION SELECT 2 UPDATE @foo SET col1 = CRYPT_GEN_RANDOM(2) % 10000 SELECT * FROM @foo
Rückgabe (2 zufällige wahrscheinlich unterschiedliche Zahlen)
col1 ---------------------- 9693 8573
Das einzige legitime Grund, an das ich denken kann, ist, dass einige Zahlen leicht überrepräsentiert sind, wenn die zufällige Zahl zwischen 0 und 65535 liegt, die nicht gleichmäßig durch 10.000 teilbar ist. Eine Möglichkeit, dies zu umgehen, besteht darin, es in eine skalare UDF zu verpacken, die eine beliebige Zahl über 60.000 wegwirft und sich rekursiv aufruft, um eine Ersatznummer zu erhalten.
CREATE FUNCTION dbo.RandomNumber() RETURNS INT AS BEGIN DECLARE @Result INT SET @Result = CRYPT_GEN_RANDOM(2) RETURN CASE WHEN @Result < 60000 OR @@NESTLEVEL = 32 THEN @Result % 10000 ELSE dbo.RandomNumber() END END
quelle
Obwohl ich CHECKSUM sehr gerne benutze, denke ich, dass ein besserer Weg die Verwendung ist
NEWID()
, nur weil Sie keine komplizierte Mathematik durchlaufen müssen, um einfache Zahlen zu generieren.Sie können die
1000
Zahl durch eine beliebige Zahl ersetzen, die Sie als Grenzwert festlegen möchten, und Sie können immer ein Pluszeichen verwenden, um einen Bereich zu erstellen. Nehmen wir an, Sie möchten eine Zufallszahl zwischen100
und200
, und Sie können Folgendes tun:Fügen Sie es in Ihrer Anfrage zusammen:
UPDATE CattleProds SET SheepTherapy= ROUND( 1000 *RAND(convert(varbinary, newid())), 0) WHERE SheepTherapy IS NULL
quelle
Ich habe 2 satzbasierte Randomisierungsmethoden gegen RAND () getestet, indem ich jeweils 100.000.000 Zeilen generiert habe. Um das Feld auszugleichen, ist der Ausgang ein Float zwischen 0-1, um RAND () nachzuahmen. Der größte Teil des Codes testet die Infrastruktur, daher fasse ich die Algorithmen hier zusammen:
-- Try #1 used (CAST(CRYPT_GEN_RANDOM(8) AS BIGINT)%500000000000000000+500000000000000000.0)/1000000000000000000 AS Val -- Try #2 used RAND(Checksum(NewId())) -- and to have a baseline to compare output with I used RAND() -- this required executing 100000000 separate insert statements
Die Verwendung von CRYPT_GEN_RANDOM war eindeutig die zufälligste, da nur eine Wahrscheinlichkeit von 0,000000001% besteht, dass beim Zupfen von 10 ^ 8 Zahlen aus einem Satz von 10 ^ 18 Zahlen sogar 1 Duplikat angezeigt wird. IOW wir hätten keine Duplikate sehen sollen und diese hatten keine! Die Erstellung dieses Sets auf meinem Laptop dauerte 44 Sekunden.
Cnt Pct ----- ---- 1 100.000000 --No duplicates
SQL Server-Ausführungszeiten: CPU-Zeit = 134795 ms, verstrichene Zeit = 39274 ms.
IF OBJECT_ID('tempdb..#T0') IS NOT NULL DROP TABLE #T0; GO WITH L0 AS (SELECT c FROM (VALUES (1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1)) AS D(c)) -- 2^4 ,L1 AS (SELECT 1 AS c FROM L0 AS A CROSS JOIN L0 AS B) -- 2^8 ,L2 AS (SELECT 1 AS c FROM L1 AS A CROSS JOIN L1 AS B) -- 2^16 ,L3 AS (SELECT 1 AS c FROM L2 AS A CROSS JOIN L2 AS B) -- 2^32 SELECT TOP 100000000 (CAST(CRYPT_GEN_RANDOM(8) AS BIGINT)%500000000000000000+500000000000000000.0)/1000000000000000000 AS Val INTO #T0 FROM L3; WITH x AS ( SELECT Val,COUNT(*) Cnt FROM #T0 GROUP BY Val ) SELECT x.Cnt,COUNT(*)/(SELECT COUNT(*)/100 FROM #T0) Pct FROM X GROUP BY x.Cnt;
Mit fast 15 Größenordnungen weniger zufällig war diese Methode nicht ganz doppelt so schnell und benötigte nur 23 Sekunden, um 100 Millionen Zahlen zu generieren.
Cnt Pct ---- ---- 1 95.450254 -- only 95% unique is absolutely horrible 2 02.222167 -- If this line were the only problem I'd say DON'T USE THIS! 3 00.034582 4 00.000409 -- 409 numbers appeared 4 times 5 00.000006 -- 6 numbers actually appeared 5 times
SQL Server-Ausführungszeiten: CPU-Zeit = 77156 ms, verstrichene Zeit = 24613 ms.
IF OBJECT_ID('tempdb..#T1') IS NOT NULL DROP TABLE #T1; GO WITH L0 AS (SELECT c FROM (VALUES (1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1)) AS D(c)) -- 2^4 ,L1 AS (SELECT 1 AS c FROM L0 AS A CROSS JOIN L0 AS B) -- 2^8 ,L2 AS (SELECT 1 AS c FROM L1 AS A CROSS JOIN L1 AS B) -- 2^16 ,L3 AS (SELECT 1 AS c FROM L2 AS A CROSS JOIN L2 AS B) -- 2^32 SELECT TOP 100000000 RAND(Checksum(NewId())) AS Val INTO #T1 FROM L3; WITH x AS ( SELECT Val,COUNT(*) Cnt FROM #T1 GROUP BY Val ) SELECT x.Cnt,COUNT(*)*1.0/(SELECT COUNT(*)/100 FROM #T1) Pct FROM X GROUP BY x.Cnt;
RAND () allein ist für die satzbasierte Generierung nutzlos. Das Generieren der Basislinie für den Vergleich der Zufälligkeit dauerte über 6 Stunden und musste mehrmals neu gestartet werden, um schließlich die richtige Anzahl von Ausgabezeilen zu erhalten. Es scheint auch, dass die Zufälligkeit zu wünschen übrig lässt, obwohl es besser ist, als die Prüfsumme (newid ()) zu verwenden, um jede Zeile neu zu säen.
Cnt Pct ---- ---- 1 99.768020 2 00.115840 3 00.000100 -- at least there were comparitively few values returned 3 times
Aufgrund der Neustarts konnte die Ausführungszeit nicht erfasst werden.
IF OBJECT_ID('tempdb..#T2') IS NOT NULL DROP TABLE #T2; GO CREATE TABLE #T2 (Val FLOAT); GO SET NOCOUNT ON; GO INSERT INTO #T2(Val) VALUES(RAND()); GO 100000000 WITH x AS ( SELECT Val,COUNT(*) Cnt FROM #T2 GROUP BY Val ) SELECT x.Cnt,COUNT(*)*1.0/(SELECT COUNT(*)/100 FROM #T2) Pct FROM X GROUP BY x.Cnt;
quelle
require_once('db/connect.php'); //rand(1000000 , 9999999); $products_query = "SELECT id FROM products"; $products_result = mysqli_query($conn, $products_query); $products_row = mysqli_fetch_array($products_result); $ids_array = []; do { array_push($ids_array, $products_row['id']); } while($products_row = mysqli_fetch_array($products_result)); /* echo '<pre>'; print_r($ids_array); echo '</pre>'; */ $row_counter = count($ids_array); for ($i=0; $i < $row_counter; $i++) { $current_row = $ids_array[$i]; $rand = rand(1000000 , 9999999); mysqli_query($conn , "UPDATE products SET code='$rand' WHERE id='$current_row'"); }
quelle