2014-01-18 22 views
0

我正在爲我正在玩的遊戲的社區開發一款「足球運動員評估」工具。 玩家信息的獲取方式如下(玩家名字,守門員得分,後衛得分,中場得分,進攻得分)。選擇前11位,共同組成MySQL中最高的綜合得分?

(爲了簡單起見,本top4的 「團隊」 組合僅由1守門員,1閃避,1月中旬,1個ATT的。)

+------+--------+-----------+-----------+----------+ 
| name | Keeper | Defender | Midfielder| Attacker | 
+------+--------+-----------+-----------+----------+ 
| John | *7.2* | 6.1 | 7.1 | 3.4 | 
| Rick | 1.9 | 9.0 | *9.2* | 5.3 | 
| Fred | 3.2 | 6.8 | 2.1 | 6.4 | 
| Mike | 2.1 | *8.9* | 8.7 | 1.2 | 
| John | 1.7 | 3.1 | 7.7 | 7.1 | 
| Doe | 4.2 | 8.9 | 8.1 | *7.9* | 
+------+--------+-----------+-----------+---------+ 
Team combination with highest total score: John (keeper), Mike (defender), Rick (mid), Doe (att) 

Total score: 7.2 + 8.9 + 9.2 + 7.9 

比方說,用戶輸入的信息用於20名球員,他想知道11個球員應該踢什麼位置,以及在哪個位置(應該有4名後衛,4名中場球員和2名攻擊者)。 合計得分越高越好。所以通過使用SQL,我想查詢11個最佳球員的數據庫,這些數據一起彌補了最高分。

我知道這可能不適用於只有一個查詢,但沒關係。我無法想出一個辦法來做到這一點,而不必像20個查詢那樣做,並逐個比較總分數。

這是我到目前爲止嘗試過的。

嘗試1: 4不同的查詢,一個用於每個位置(門將,後衛,等等)

SELECT name,midfielder_score FROM players WHERE id NOT IN (" . implode(',', $alreadyUsedPlayers) . ") ORDER BY midfielder_score DESC LIMIT 4 

要獲得4級最好的中場。這種方法的問題在於,如果在這個階段(當選擇中場球員時)沒有選擇好的球員,那麼總得分可能會增加,而是留給攻擊者選擇。

嘗試2: 結合GRUOP BY與和

SELECT name, SUM(keeper_score) AS totalKeeperScore [...] FROM players GROUP BY name ORDER BY totalKeeperSCore DESC LIMIT 11 

但我意識到,這也必須與多個查詢,並且通過比較來完成。

任何想法如何解決這個問題? 謝謝。

+1

如果明白這個正確的,那麼裏克,而不是麥克,是收視率最高的後衛。 – BlackHatSamurai

+0

單獨是,但考慮這裏重要的是總體總分。通過不選擇瑞克作爲防守隊員,總得分爲0.1。 – Jonathan

+0

總分0.6,我的意思是。看看爲什麼在下面的例子: 裏克後衛:7.2 + 9.0 + 8.7 + 7.9 = 32.8 邁克後衛:7.2 + 8.9 + 9.2 + 7.9 = 33.2 – Jonathan

回答

0

我會做4個查詢。這裏的僞代碼,我會用這樣的:

創建關聯數組:

$player["attacker"] 
$player["defender"] 
$player["midfield"] 
$player["keeper"] 

的爲每個位置,順序按分數查詢,並將其放置在降序(最高到最低)。

以第一個位置的最高分數並將其添加到第一個數組。 拿第二個位置得分最高,確保玩家沒有被選中以前的位置, 如果沒有, 然後添加到下一個數組。 如果玩家已被選中,請獲得下一位玩家,並檢查並確保他們沒有被選中。

按照這個過程,檢查最高分,並確保他們的球員沒有被分配一個位置,直到所有4個位置都被填滿。

+0

你建議的基本上我在提及嘗試1。這個解決方案不會產生11名球員中最好的陣容。爲什麼?例如,如果在第二輪挑選一名球員(在選擇防守隊員時),則不考慮這樣一個事實:如果該球員被留給中場選秀權,整體11分可能會更高。明白了嗎? – Jonathan

+0

@Jonathan您根據最高排名,即第一個結果返回您的查詢結果,是最高分數,無論位置如何。通過這種方式,您可以獲得最高分,並獲得最高分。 – BlackHatSamurai

+0

那我一定誤解了你。你能否給我一個完整的例子,讓我明白你的意思? – Jonathan

2

您可以通過使用cross join和適當的子查詢來構建所有可能的團隊。然後,只需將分數相加,然後使用order bylimit來選擇最佳團隊。

select k.name as keeper_name, d.name as defender_name, 
     m.name as midfield_name, a.name as attacker_name, 
     (keeper + defender + midfield + attacker) as score 
from (select name, keeper 
     from top4 
    ) k cross join 
    (select name, defender 
     from top4 
    ) d cross join 
    (select name, midfield 
     from top4 
    ) m cross join 
    (select name, attacker 
     from top4 
    ) a 
order by score desc 
limit 1; 

編輯:

Here是一個SQL小提琴,顯示的查詢工作。此查詢的版本增加了一個where條款,以防止一個人在兩個角色是:

where k.name not in (d.name, m.name, a.name) and 
     d.name not in (m.name, a.name) and 
     m.name not in (a.name) 
+0

聽起來不錯,因爲我不太擅長SQL,所以我無法得到這個工作。你介意更新你的答案確切的列名(等),所以我可以將其粘貼到我的文件,看看它是否產生正確的結果?例如,k.name是正確的語法嗎? top4,那是什麼,而不是表名正確? – Jonathan

+0

@Jonathan。 。 。列名基於您在問題頂部提供的示例數據。 –

+0

好,所以我想「top4」是表名。你確定這是完全正確的,phpMyAdmin的SQL部分只是繼續加載,並加載和加載。 「#1317 - 查詢執行被中斷」。有任何想法嗎?儘管我喜歡這個解決方案。 – Jonathan