2

我有两张桌子:

  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 中选择所有玩家,计算他们的分数并按得分最高的前 3 名玩家排序,而其他人将按照他们的姓氏排序?例如我有六个玩家:

表 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                                   |
+-----------+----------------------------------------+
4

5 回答 5

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
于 2013-07-18T12:55:20.687 回答
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;

可以完成这项工作。

于 2013-07-18T12:49:50.740 回答
0

这应该可以解决问题。加入子选择以获得前 3 名,按他们的分数降序排列。不在前三名的球员不会有分数,所以他们从前三名子选择中的分数将为NULL(因为他们没有匹配前三名之一),他们将出现在前三名之后。他们将被简单排序按姓氏排序。

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
于 2013-07-18T12:52:03.273 回答
0
(SELECT * FROM user ORDER BY user_id DESC LIMIT 2)
UNION
(SELECT * FROM user ORDER BY username);
于 2013-07-18T12:58:17.063 回答
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
于 2013-07-18T13:57:54.253 回答