【问题标题】:SQL Query for selecting multiple rows but highest value for each PK用于选择多行但每个 PK 的最高值的 SQL 查询
【发布时间】:2015-12-23 07:34:05
【问题描述】:

我知道标题听起来很糟糕,但我不知道如何更好地总结它。我很确定以前有人遇到过同样的问题,但我找不到任何东西。关系型数据库:MySQL。

问题: 我有以下(简化的)表:

+------+------------+---------------------------------+
| name | date       | score                           |
+------+------------+---------------------------------+
| A    | 01.01.2015 | 1                               |
| A    | 01.02.2015 | 3                               |
| A    | 01.03.2015 | 4                               |
| B    | 01.01.2015 | 3                               |
| B    | 01.02.2015 | 4                               |
| B    | 01.03.2015 | 5                               |
| C    | 01.01.2015 | 1                               |
| C    | 01.02.2015 | 2                               |
| C    | 01.03.2015 | 3                               |
+------+------------+---------------------------------+

没有定义唯一约束或 PK。

表格代表游戏的高分。每天都会插入所有玩家的分数,这些值包括:姓名、积分、now()、...

数据代表每个球员在特定时间的得分快照。

我只想为每个用户提供最新条目,但只为最高 X 玩家提供。所以结果应该是这样的

+------+------------+---------------------------------+
| name | date       | score                           |
+------+------------+---------------------------------+
| A    | 01.03.2015 | 4                               |
| B    | 01.03.2015 | 5                               |
+------+------------+---------------------------------+
  • C 没有出现,因为他不在前 2 名(按分数)
  • A 出现在最近的行中(按日期)
  • B 与 A 一样出现在最近的行中(按日期),因为他在前 2 位

我希望我的意思很清楚。

提前致谢!

【问题讨论】:

  • Google 并了解 SQL 中的“GROUP BY”和 MAX()。
  • 那么,获取每个名称的max(date) 列表并获取max(Score), name... ORDER BY maxscore desc LIMIT 2 列表然后只返回两个列表匹配的结果的逻辑是什么?
  • 假设有名称 A、B、C、D、E 和 F。对于每个名称,存在多个具有不同日期和分数的行。日期越近,得分越高(当然,如果玩家是活跃的)。所以我想要的是 A、B、C、D、E 和 F 中每一个的最新行(按日期)。可选地,最好将其限制为最高的 5 个(或其他)玩家分数

标签: mysql sql


【解决方案1】:

我知道您需要先选择获得最高分的 X 名球员,然后再获得他们的最新表现。在这种情况下,您应该这样做:

SELECT * 
FROM tablename t
JOIN
(
  SELECT t.name, max(t.date) as max_date
  FROM tablename t
  JOIN
  (
    SELECT name 
    FROM
    (
      SELECT name, max(score) as max_score
      FROM table_name
      GROUP BY name
    ) all_highscores
    ORDER BY max_score DESC
    LIMIT X
  ) top_scores
  ON top_scores.name = t.name
  GROUP BY t.name
) top_last
on t.name = top_last.name
and t.date = top_last.date;

【讨论】:

  • 完美,谢谢!!我可以根据自己的需要进行调整,感谢您的帮助!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-01-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-06-21
相关资源
最近更新 更多