如何使用PHP打破MySQL查询的平局


How can I break the tie from my MySQL query using PHP?

我正在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

@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首先出现,如图所示。

您可以添加第二个ORDER BY变量,因此如果您希望它先按sum排序,然后按candidate_no-desc排序,则它将变为"ORDER BY sum-desc,candidate_no-desc"。