我正在为我正在玩的游戏社区开发一个“足球运动员评估”工具。球员信息存储如下(球员的名字,他的门将得分,后卫得分,中场得分,进攻得分)。
(为了简单起见,top4的“团队”组合只有一个守门员,一个def,一个中间,一个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位最佳球员的db,这些人加在一起构成了最高的分数。
我意识到这在一个查询中可能不起作用,但这很好。我只是想不出一种方法来做到这一点,不需要做20个查询和比较总分,一个一个。
这就是我到目前为止尝试过的。
尝试1:4个不同的查询,每个位置一个(守门员,后卫,等等)
SELECT name,midfielder_score FROM players WHERE id NOT IN (" . implode(',', $alreadyUsedPlayers) . ") ORDER BY midfielder_score DESC LIMIT 4
得到四名最好的中场。这种方法的问题在于,如果在这个阶段没有挑选出一个好球员(当选择中场时),而是留给进攻者选择,那么总得分可能不会增加。
尝试2:将GRUOP与sum结合
SELECT name, SUM(keeper_score) AS totalKeeperScore [...] FROM players GROUP BY name ORDER BY totalKeeperSCore DESC LIMIT 11
但我意识到,这也必须通过多个查询和比较来完成。
有什么办法解决这个问题吗?谢谢。
发布于 2014-01-18 03:45:09
您可以通过使用带有适当子查询的cross join
来构建所有可能的团队。然后,简单地将分数相加,并使用order by
和limit
来选择最好的团队。
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;
编辑:
这里是一个显示查询工作情况的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)
发布于 2014-01-18 03:36:18
我会做4次查询。在这里,我将使用的psuedo代码:
创建一个关联数组:
$player["attacker"]
$player["defender"]
$player["midfield"]
$player["keeper"]
对每个职位进行查询,按分数排序,然后按降序排列(从最高到最低)。
第一个位置的得分最高,并将其添加到第一个数组中。取得第二个位置最高的分数,确保球员还没有被选中之前的位置,如果没有,然后添加到下一个数组。如果该播放器已被选中,获取下一个播放器,并检查,以确保他们没有被选中。
按照这个过程,检查最高的分数,并确保他们的球员没有被分配一个位置,直到所有的4个职位已经填补。
https://stackoverflow.com/questions/21199563
复制相似问题