UPDATE CattleProds
SET SheepTherapy=(ROUND((RAND()* 10000),0))
WHERE SheepTherapy IS NULL
আমি যদি তখন একটি নির্বাচন করি আমি দেখতে পাচ্ছি যে আমার এলোমেলো সংখ্যাটি প্রতিটি সারিতে অভিন্ন । কোনও ধারণা কীভাবে অনন্য এলোমেলো সংখ্যা তৈরি করবেন?
UPDATE CattleProds
SET SheepTherapy=(ROUND((RAND()* 10000),0))
WHERE SheepTherapy IS NULL
আমি যদি তখন একটি নির্বাচন করি আমি দেখতে পাচ্ছি যে আমার এলোমেলো সংখ্যাটি প্রতিটি সারিতে অভিন্ন । কোনও ধারণা কীভাবে অনন্য এলোমেলো সংখ্যা তৈরি করবেন?
উত্তর:
পরিবর্তে rand(), ব্যবহার করুন newid(), যা ফলাফল প্রতিটি সারি জন্য পুনরায় গণনা করা হয়। স্বাভাবিক উপায় হ'ল চেকসামের মডুলো ব্যবহার করা। নোট করুন যে checksum(newid())-2,147,483,648 উত্পাদন করতে পারে এবং পূর্ণসংখ্যার ওভারফ্লো হতে পারে abs(), সুতরাং আমাদের চেকসাম রিটার্ন মানকে পরম মানের রূপান্তর করার আগে মডুলো ব্যবহার করা উচিত।
UPDATE CattleProds
SET SheepTherapy = abs(checksum(NewId()) % 10000)
WHERE SheepTherapy IS NULL
এটি 0 এবং 9999 এর মধ্যে একটি এলোমেলো সংখ্যা উত্পন্ন করে।
আপনি এসকিউএল সার্ভার ২০০৮ এ থাকলে আপনি এটিও ব্যবহার করতে পারেন
CRYPT_GEN_RANDOM(2) % 10000
যা কিছুটা সহজ বলে মনে হচ্ছে (এটি প্রতি সারিতে একবারেও মূল্যায়ন করা newidহয় - নীচে দেখানো হয়েছে)
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
রিটার্ন (2 এলোমেলো সম্ভবত বিভিন্ন সংখ্যা)
col1
----------------------
9693
8573
অপ্রকাশিত ডাউনভোটকে কেবলমাত্র বৈধ কারণ হিসাবে আমি ভাবতে পারি তা হ'ল এটি যেহেতু উত্পন্ন এলোমেলো সংখ্যা 0-65535 এর মধ্যে যা 10,000 দ্বারা সমানভাবে বিভাজ্য নয় কিছু কিছু সংখ্যক উপস্থাপনের চেয়ে বেশি হবে। এর চারপাশের উপায় হ'ল এটি একটি স্কেলার ইউডিএফের মধ্যে মোড়ানো যা কোনও সংখ্যা 60০,০০০ এরও বেশি ফেলে দেয় এবং নিজেকে প্রতিস্থাপনের নম্বর পাওয়ার জন্য পুনরাবৃত্তি বলে।
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
যদিও আমি চেকসুম ব্যবহার করতে পছন্দ করি না, আমি অনুভব করি যে আরও ভালতর একটি উপায় ব্যবহার করা হচ্ছে NEWID()কেবল আপনাকে সাধারণ সংখ্যা উত্পন্ন করতে কোনও জটিল গণিতের মধ্য দিয়ে যেতে হবে না।
ROUND( 1000 *RAND(convert(varbinary, newid())), 0)
আপনি 1000সীমা হিসাবে সেট করতে চান এমন যে কোনও সংখ্যার সাথে আপনি এটি প্রতিস্থাপন করতে পারেন এবং আপনি সর্বদা একটি পরিসীমা তৈরি করতে একটি প্লাস চিহ্ন ব্যবহার করতে পারেন, যাক এর মধ্যে আপনি একটি এলোমেলো সংখ্যা চান 100এবং 200আপনি এর মতো কিছু করতে পারেন:
100 + ROUND( 100 *RAND(convert(varbinary, newid())), 0)
এটিকে আপনার প্রশ্নের সাথে একত্র করা:
UPDATE CattleProds
SET SheepTherapy= ROUND( 1000 *RAND(convert(varbinary, newid())), 0)
WHERE SheepTherapy IS NULL
আমি প্রতিটি সেট সহ 100,000,000 সারি তৈরি করে RAND () এর বিপরীতে 2 সেট ভিত্তিক র্যান্ডমাইজেশন পদ্ধতি পরীক্ষা করেছি। ক্ষেত্রটি সমতল করতে আউটপুটটি 0-1 থেকে নকল RAND () এর মধ্যে একটি ভাসমান। কোডটির বেশিরভাগই পরিকাঠামো পরীক্ষা করে যাচ্ছি তাই আমি এখানে অ্যালগরিদমগুলি সংক্ষেপ করে বলছি:
-- 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
CRYPT_GEN_RANDOM ব্যবহার করা স্পষ্টতই এলোমেলো ছিল যেহেতু 10 ^ 18 সংখ্যার একটি সেট থেকে 10 ^ 8 নম্বরগুলি সংগ্রহ করার সময় কেবল 1 ডুপ্লিকেট দেখার জন্য এমনকি .0000000011% সম্ভাবনা রয়েছে। IW আমাদের কোন সদৃশ দেখা উচিত ছিল না এবং এই কিছুই ছিল না! এই সেটটি আমার ল্যাপটপে উত্পন্ন করতে 44 সেকেন্ড সময় নিয়েছে।
Cnt Pct
----- ----
1 100.000000 --No duplicates
এসকিউএল সার্ভার এক্সিকিউশন টাইমস: সিপিইউ সময় = 134795 এমএস, অতিবাহিত সময় = 39274 এমএস।
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;
কম এলোমেলো আকারের প্রায় 15 টি আদেশে এই পদ্ধতিটি দ্বিগুণ দ্রুত ছিল না, 100 এম সংখ্যা উত্পন্ন করতে কেবল 23 সেকেন্ড সময় নেয়।
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
এসকিউএল সার্ভার এক্সিকিউশন টাইমস: সিপিইউ সময় = 77156 এমএস, অতিবাহিত সময় = 24613 এমএস।
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 () একা সেট-ভিত্তিক প্রজন্মের পক্ষে অকেজো, সুতরাং এলোমেলোতার তুলনা করার জন্য বেসলাইন তৈরি করতে hours ঘন্টা সময় নেয় এবং অবশেষে আউটপুট সারিগুলির সঠিক সংখ্যা পেতে বেশ কয়েকবার পুনরায় চালু করতে হয়েছিল। এটি আরও মনে হয় যে এলোমেলোভাবে পছন্দসই হওয়ার জন্য অনেক কিছু ছেড়ে যায় যদিও প্রতিটি সারিতে পুনরায় পুনরায় পরীক্ষা করতে চেকসাম (নতুনড ()) ব্যবহার করা ভাল than
Cnt Pct
---- ----
1 99.768020
2 00.115840
3 00.000100 -- at least there were comparitively few values returned 3 times
পুনঃসূচনাগুলির কারণে, মৃত্যুদণ্ড কার্যকর করার সময় ক্যাপচার করা যায়নি।
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;
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'");
}