我的任務是創建一個秘密的圣誕老人站點,用戶登錄并從資料庫中隨機選擇一個名稱。條件是你不畫你自己的名字,但因為一次只選一個名字,我遇到了下面提到的問題:3個人是(比爾,邁克和杰克)比爾<邁克邁克<比爾如果邁克和比爾得到對方,杰克不會有伙伴。我可以撰寫一小段代碼來避免這種情況,當涉及到少數人時,我正在徘徊,如果他們還有其他方法可以解決這個問題。我當前的 php 代碼
$sql ="SELECT gifted
FROM gifts
WHERE gifted != '$username'
AND isgifted = 0
ORDER BY Rand()
LIMIT 1";
uj5u.com熱心網友回復:
我認為解決這個問題的簡單演算法是:
- 獲取所有參與者的串列,使用 SQL rand()函式按隨機順序排序。
- 對于隨機串列中的每一行,從下一行為每個人分配一個秘密圣誕老人。例如,第 1 行將被指定為第 2 行作為他/她的圣誕老人。第 2 行將被分配到第 3 行,依此類推。為此使用 sql Lead()函式。
- 對于串列中的最后一行,回圈回傳并將第一行指定為他/她的圣誕老人。為此使用first_value()函式。
在 PHP 應用程式的記憶體中執行此操作可能最容易,但由于此問題主要與 SQL 相關,因此這里提供一個純 SQL 解決方案。假設您有一個名為“people”的表,其中包含“name”和“id”列,這將為您提供所需的結果:
SELECT name,
(CASE
WHEN secret_santa IS NULL
THEN first
ELSE secret_santa
END) secret_santa
FROM (
SELECT name,secret_santa,(FIRST_VALUE(name) over ()) as first FROM (
SELECT name,id,secret_santa
FROM (
SELECT name, id, LEAD(name) OVER (ORDER BY RAND()) secret_santa
FROM people
) santas
) randomized
) wraparound
輸出:
------ --------------
| name | secret_santa |
------ --------------
| Mike | Jake |
| Jake | Bill |
| Bill | Mike |
------ --------------
請注意,這里的所有復雜性都來自需要將最后一行環繞到第一行。如果你愿意容忍一個沒有圣誕老人的人用自定義代碼來修復,那么 SQL 就是:
SELECT name, LEAD(name) OVER (ORDER BY RAND()) secret_santa
FROM people
輸出:
------ --------------
| name | secret_santa |
------ --------------
| Bill | Mike |
| Mike | Jake |
| Jake | NULL |
------ --------------
這里的作業示例
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/380088.html
