[英]How to insert a random number which is not present in MySQL table?
$sql = "INSERT INTO foldertable ( folderid )
SELECT (
SELECT random_num
FROM (
SELECT FLOOR(RAND() * 4 + 1) AS random_num
) AS numbers_mst_plus_1
WHERE random_num NOT IN (
0,1
)
)";
它插入一個隨機數。 但有時它只是簡單地插入 0。
當下面的 SQL 返回一個等於 0 或 1 的數字時,它是插入零。
SELECT random_num
FROM (
SELECT FLOOR(RAND() * 4 + 1) AS random_num
) AS numbers_mst_plus_1
WHERE random_num NOT IN (
0,1
)
select 查詢到 select 一個數字,直到它對於該列是唯一的。
我創建了一個選擇 1,2,3,4,5 的 select 語句
SELECT random_num
FROM (
SELECT 1 AS random_num
UNION
SELECT 2 AS random_num
UNION
SELECT 3 AS random_num
UNION
SELECT 4 AS random_num
UNION
SELECT 5 AS random_num
) AS numbers_mst_plus_1
然后嘗試在 INSERT QUERY 中實現它
$sql = "INSERT INTO foldertable ( folderid )
SELECT (SELECT random_num FROM (SELECT 1 AS random_num UNION SELECT 2 AS random_num) AS temp_table WHERE random_num NOT IN (1) LIMIT 1
)
上面的查詢總是將 2 插入到表中,我很高興。 然后我想如果NOT IN
中同時存在 1 和 2 (真實的,例如Not in
Clause 包含表中存在的所有文件夾 id)
問題就在那里 -----
$sql = "INSERT INTO foldertable ( folderid )
SELECT (SELECT random_num FROM (SELECT 1 AS random_num UNION SELECT 2 AS random_num) AS temp_table WHERE random_num NOT IN (1 , 2) LIMIT 1
)
";
現在它再次在folderid
列中輸入0
所以我在其中添加了WHERE
CLAUSE
$sql = "INSERT INTO foldertable ( folderid )
SELECT (SELECT random_num FROM
(SELECT 1 AS random_num UNION SELECT 2 AS random_num UNION SELECT 3 AS random_num )
AS temp_table
WHERE random_num
NOT IN (
SELECT folderid FROM foldertable
)
LIMIT 1
)
WHERE ((SELECT COUNT(*) FROM foldertable) < 3)
";
因此,如果使用了所有 ID,現在它不會添加新行。
但真正的痛苦是寫作
SELECT 1 AS random_num
UNION
SELECT 2 AS random_num
UNION
SELECT 3 AS random_num
UNION
SELECT 4 AS random_num
UNION
SELECT 5 AS random_num
.... 100000000 times
UNION
SELECCT 100000006 AS random_num
所以這不值得時間
所以GOD FOR LOOP
來了
$randomNoString = "";
for ($i=0; $i < ($maxFolderId - $minFolderId + 1 ); $i++) {
if($i === 0){
$randomNoString ="SELECT ".($minFolderId + $i) . " AS random_num" ;
}
else {
$randomNoString = $randomNoString ." UNION " . "SELECT ".($minFolderId + $i) . " AS random_num";
}
}
$sql = "INSERT INTO foldertable ( folderid )
SELECT (SELECT random_num FROM
({$randomNoString})
AS temp_table
WHERE random_num
NOT IN (
SELECT folderid FROM foldertable
)
LIMIT 1
)
WHERE ((SELECT COUNT(*) FROM foldertable) < {$maxFolderCount})
";
1. 現在文件夾 ID 是唯一的,但不是隨機的。 2. 我的想法是說它會產生性能問題。
folderid
設置為唯一。方案A——Hash:
使用散列 function 創建一個新號碼。 這取決於已經具有AUTO_INCREMENT id
的表:
SELECT MD5(MAX(id)) FROM t
優點:簡單、快速
缺點:需要id
,“數字”實際上是一個 32 字符的十六進制字符串。
B計划——預建清單:
建立了一個數字 100..50000 的表nums
。
將它們洗牌到不同的表中:
CREATE TABLE rand_nums SELECT num FROM nums ORDER BY RAND();
提取一個數字
SELECT num FROM rand_nums LIMIT 1; -- get DELETE FROM rand_nums WHERE num =...; -- remove
優點:高效(在 setup_
缺點:需要更多復雜性來處理步驟 3 中數字和效率的並發獲取
計划 C -- 其他想法
如果您后退一步,您可能會發現更高級別的目標可以用其他一些技術代替。 而且您可能需要“獲取隨機行”作為原語。 如果是這樣,這里有一些“相當不錯”的技術: http://mysql.rjweb.org/doc.php/random
關於:
select concat(
cast(char(64+floor(rand()*26+1)) as char),
cast(char(64+floor(rand()*26+1)) as char),
cast(char(64+floor(rand()*26+1)) as char),
cast(char(64+floor(rand()*26+1)) as char),
cast(char(64+floor(rand()*26+1)) as char),
cast(char(64+floor(rand()*26+1)) as char)) as char6;
或者,如果您想要更長的語句:
with recursive cte as (
select 'A' as a
union all
select CHAR(ORD(a)+1)
from cte
where a<'Z')
select concat(c1.a,c2.a,c3.a,c4.a,c5.a,c6.a) as char6
from cte c1
cross join (select a from cte order by rand()*26+1 limit 1) c2
cross join (select a from cte order by rand()*26+1 limit 1) c3
cross join (select a from cte order by rand()*26+1 limit 1) c4
cross join (select a from cte order by rand()*26+1 limit 1) c5
cross join (select a from cte order by rand()*26+1 limit 1) c6
order by rand()*26+1
limit 1;
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.