MySQL命令得分最高

时间:2013-07-18 12:41:44

标签: mysql select sql-order-by

我有两张桌子:

  CREATE TABLE `fl_poll` (
  `id_poll` int(11) NOT NULL AUTO_INCREMENT,
  `id_player` int(11) NOT NULL,
  `position` varchar(50) NOT NULL,
  `score` int(11) NOT NULL,
  `time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  `ip` varchar(100) NOT NULL,
  PRIMARY KEY (`id_anketa`)
) ENGINE=MyISAM;

CREATE TABLE `fl_player` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `id_team` int(11) NOT NULL,
  `name` varchar(100) NOT NULL,
  `lastname` varchar(100) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM;

我想问一下,如果选择表fl_player中的所有玩家,是否有任何解决方案,计算得分最高的前三名玩家的得分和顺序,其他人将按姓氏排序?例如,我有六个玩家:

表fl_player:

id     |     lastname    
------------------------
1             Smith           
2            Johnson          
3             Todd             
4             Dragon            
5             Bond             
6             Black       

表fl_poll:

+-----------+-------+
| id_player | score |
+-----------+-------+
|         1 |     2 |
|         2 |     4 |
|         3 |     6 |
|         4 |     8 |
|         5 |    10 |
|         6 |    12 |
+-----------+-------+

我希望这样的结果:

+-----------+----------------------------------------+
| id_player |                lastname                |
+-----------+----------------------------------------+
|         6 | Black <-- top 3 with highest score     |
|         5 | Bond                                   |
|         4 | Dragon                                 |
|         2 | Johnson <-- from now order by lastname |
|         1 | Smith                                  |
|         3 | Todd                                   |
+-----------+----------------------------------------+

5 个答案:

答案 0 :(得分:2)

  SELECT   fl_poll.id_player, fl_player.lastname, fl_poll.score, 1 AS type
  FROM     fl_player
      JOIN fl_poll ON fl_poll.id_player = fl_player.id
  WHERE    fl_poll.score >= (
             SELECT MIN(score) FROM (
               SELECT score FROM fl_poll ORDER BY score DESC LIMIT 3
             ) t
           )

UNION

  SELECT   fl_poll.id_player, fl_player.lastname, fl_poll.score, 2 AS type
  FROM     fl_player
      JOIN fl_poll ON fl_poll.id_player = fl_player.id
  WHERE    fl_poll.score < (
             SELECT MIN(score) FROM (
               SELECT score FROM fl_poll ORDER BY score DESC LIMIT 3
             ) t
           )

ORDER BY CASE WHEN type = 1 THEN score END DESC, lastname

答案 1 :(得分:0)

这样的东西
SELECT s.id_player, n.lastname FROM fl_poll AS s INNER JOIN fl_player AS n ON n._id = s.id_player ORDER BY s.score DESC;

可以胜任。

答案 2 :(得分:0)

这应该可以解决问题。加入子选择以获得前三名,按降序排列。不在前三名中的玩家将没有得分,因此他们从top3子选择中得分将为NULL(因为他们与前3名中的一名不匹配),并且他们将出现在前3名之后。他们将被简单地排序按顺序排列。

SELECT po.id_player, lastname

FROM   fl_player pl

     LEFT JOIN 

(

SELECT pl.id, SUM(score) score

FROM   fl_player pl

       JOIN fl_poll po ON pl.id = po.id_player

GROUP BY pl.id

ORDER BY SUM(score) DESC

LIMIT 3

) as top3 on fl.id = top3.id

ORDER BY top3.score DESC, last_name

如果您想要包含每位玩家的分数,请使用此选项:

SELECT po.id_player, lastname, SUM(score) score

FROM   fl_player pl

       JOIN fl_poll po ON pl.id = po.id_player

     LEFT JOIN 

(

SELECT pl.id, SUM(score) score

FROM   fl_player pl

       JOIN fl_poll po ON pl.id = po.id_player

GROUP BY pl.id

ORDER BY SUM(score) DESC

LIMIT 3

) as top3 on fl.id = top3.id

GROUP BY pl.id

ORDER BY top3.score DESC, last_name

答案 3 :(得分:0)

(SELECT * FROM user ORDER BY user_id DESC LIMIT 2)
UNION
(SELECT * FROM user ORDER BY username);

答案 4 :(得分:0)

依赖union按特定顺序返回结果是非常危险的(也是错误的)。

这是一种完全不同的方法。按分数创建前三个ID的列表。如果用户在该列表中,则按分数对其进行排序。否则按名称命名。

您可以使用substring_index(group_concat( . . . ))获取列表。其余的只是设置order by子句来使用此信息:

select p.id_player, p.lastname
from fl_player p cross join
     (select substring_index(group_concat(id order by score desc), ',', 3) as ids
      from fl_player
     ) top3
order by find_in_set(id, top3.ids) > 0,
         (case when find_in_set(id, top3.ids) > 0 then score end) desc,
         name