【问题标题】:How can I break the tie from my MySQL query using PHP?如何使用 PHP 打破与 MySQL 查询的关系?
【发布时间】:2013-07-15 14:56:48
【问题描述】:

我正在 XAMMP 中使用 PHP ang MySQL 或 PhpMyAdmin 创建一个选美评分系统。我以某种方式设法使用 MySQL 获得候选人的排名,但有些情况下可以取得联系。如何打破使用 PHP 查询结果的平局?

候选人的排名是根据他们在一个有5名评委和9名候选人的类别中的分数。所以我真的不知道该怎么做或如何在 PHP 中解决它。

如果我希望 C9 排名第一而不是 C4 怎么办?

这是我的数据库...希望有人可以帮助我。提前致谢。

CREATE TABLE IF NOT EXISTS score (
 candidate_no varchar(5) NOT NULL  ,
 category_no varchar(5) NOT NULL  ,
 judge_id varchar(5) NOT NULL  ,
 score int(3),
 PRIMARY KEY (candidate_no,category_no,judge_id),
 KEY score_fkey (judge_id),
 KEY score_fkey3 (category_no)) ;



INSERT INTO  score  (candidate_no,  category_no,  judge_id,  score) VALUES
('C1', 'cat1', 'J1', 17),
('C1', 'cat1', 'J2', 15),
('C1', 'cat1', 'J3', 17),
('C1', 'cat1', 'J4', 18),
('C1', 'cat1', 'J5', 19),
('C2', 'cat1', 'J1', 17  ),
('C2', 'cat1', 'J2', 15  ),
('C2', 'cat1', 'J3', 16  ),
('C2', 'cat1', 'J4', 18  ),
('C2', 'cat1', 'J5', 18  ),
('C3', 'cat1', 'J1', 15  ),
('C3', 'cat1', 'J2', 20  ),
('C3', 'cat1', 'J3', 19  ),
('C3', 'cat1', 'J4', 16  ),
('C3', 'cat1', 'J5', 19  ),
('C4', 'cat1', 'J1', 19 ),
('C4', 'cat1', 'J2', 20  ),
('C4', 'cat1', 'J3', 18  ),
('C4', 'cat1', 'J4', 18  ),
('C4', 'cat1', 'J5', 19  ),
('C5', 'cat1', 'J1', 18  ),
('C5', 'cat1', 'J2', 16 ),
('C5', 'cat1', 'J3', 18  ),
('C5', 'cat1', 'J4', 18  ),
('C5', 'cat1', 'J5', 18  ),
('C6', 'cat1', 'J1', 20  ),
('C6', 'cat1', 'J2', 16 ),
('C6', 'cat1', 'J3', 16  ),
('C6', 'cat1', 'J4', 16  ),
('C6', 'cat1', 'J5', 17  ),
('C7', 'cat1', 'J1', 11 ),
('C7', 'cat1', 'J2', 12  ),
('C7', 'cat1', 'J3', 14  ),
('C7', 'cat1', 'J4', 15  ),
('C7', 'cat1', 'J5', 17  ),
('C8', 'cat1', 'J1', 15  ),
('C8', 'cat1', 'J2', 16  ),
('C8', 'cat1', 'J3', 18  ),
('C8', 'cat1', 'J4', 17 ),
('C8', 'cat1', 'J5', 17  ),
('C9', 'cat1', 'J1', 19  ),
('C9', 'cat1', 'J2', 19  ),
('C9', 'cat1', 'J3', 19  ),
('C9', 'cat1', 'J4', 19  ),
('C9', 'cat1', 'J5', 18  );

这是我的查询:

select      sum
            ,candidate_no
            ,@curRank := @curRank + 1 AS rank

from(  

select      sum(score) / 5 sum
            ,candidate_no
from        score
where       candidate_no = 'c1'

union
select      sum(score) / 5 sum
            ,candidate_no
from        score
where       candidate_no = 'c2'

union
select      sum(score) / 5 sum
            ,candidate_no
from        score
where       candidate_no = 'c3'

union
select      sum(score) / 5 sum
            ,candidate_no
from        score
where       candidate_no = 'c4'

union
select      sum(score) / 5 sum
            ,candidate_no
from        score
where       candidate_no = 'c5'

union
select      sum(score) / 5 sum
            ,candidate_no
from        score
where       candidate_no = 'c6'

union
select      sum(score) / 5 sum
            ,candidate_no
from        score
where       candidate_no = 'c9'

) a , (SELECT @curRank := 0) r
order by sum desc

结果将是..

sum       | candidate_no | rank
18.8000   | C4           |    1
18.8000   | C9           |    2
17.8000   | C3           |    3
17.6000   | C5           |    4
17.2000   | C1           |    5
17.0000   | C6           |    6
16.8000   | C2           |    7
16.6000   | C8           |    8
13.8000   | C7           |    9

【问题讨论】:

  • 只是为了澄清 - 这是想要的结果,对吧?即使候选 C4 和 C9 的分数相同,C4 还是平局?
  • 你为什么使用 UNION 而不是 GROUP BY candidate_no
  • 也许您可以添加一个preference 列,如果您希望它在相同分数的情况下成为第一个,请将其设置为1。对preference上的分数进行排序。
  • 很简单,在sqlfiddle 上运行它,你会得到想要的结果。 ;p 只需向 sqlfiddle 添加一个 ref 以便任何想玩它的人都可以
  • @Barmar :好吧,因为我不擅长查询。我会用它。谢谢。

标签: php mysql xampp


【解决方案1】:

@JHaasie77 有一个很好的方法,使用 candidate_no 作为排序器(然后归结为字母数字排序顺序),当您使用降序时,首先使 9。 (同样,如果您使用升序,C9 将是最后一个)。如果没有进一步的取消资格,那么这是最简单的路线。

如果您根据其他指标做出订购决定,您可能希望更改您的表格以添加其他一些您可以订购的列。 (也许是“家乡英雄”与“游客”的对比,或者是年龄最小的匹配者优先——谁知道呢。)但是任何其他细节都需要添加到数据库中,这样你就可以使用它来创建结果中的偏好。

话虽如此,您可以通过使用GROUP BY 而不是联合来稍微简化该查询。这也使它足够动态,如果将来有更多候选人,查询将自动重新调整。因此,您的长查询现在变为:

SELECT      sum
            ,candidate_no
            ,@curRank := @curRank + 1 AS rank
FROM        (
              SELECT      SUM(score) / 5 SUM
                         ,candidate_no
              FROM        SCORE
              GROUP BY    candidate_no
            ) a
            , (
              SELECT @curRank := 0
            ) r
ORDER BY    sum DESC
            ,candidate_no DESC

这基本上意味着对于每个唯一的candidate_num,它会将分数相加并除以 5。上面还为candidate_num 添加了第二个排序器,使C9 首先出现as seen here

【讨论】:

  • 非常感谢。它帮助了我。
【解决方案2】:

您可以添加第二个 ORDER BY 变量,因此如果您希望它先按总和然后按候选编号排序,则它变为“ORDER BY sum desc,candidate_no desc”。第二。

【讨论】:

  • 谢谢。这对我有帮助。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-04-26
  • 1970-01-01
  • 1970-01-01
  • 2015-08-20
  • 1970-01-01
  • 2020-11-08
  • 2012-01-27
相关资源
最近更新 更多