1

我正在研究一个体育数据库,我想编写一个查询来返回某些类别的名称和统计值。例如,目标领先者、助攻领先者、得分领先者、+/- 领先者、罚时领先者等。我正在使用一个名为 NJDSkaters 的表格,其中包含来自特定球队的球员姓名和统计数据。下面是查询代码:

SELECT CONCAT(PlayerName,' - ',Goals) AS GoalLeader, CONCAT(PlayerName,' - ',Assists)
    CONCAT(PlayerName,' - ',Points) AS PointsLeader
FROM NJDSkaters
WHERE Goals = (SELECT DISTINCT MAX(Goals) FROM NJDSkaters)
    OR Assists = (SELECT DISTINCT MAX(Assists) FROM NJDSkaters)
    OR Points = (SELECT DISTINCT MAX(Points) FROM NJDSkaters);

这是我的滑冰者注册表中的一个片段,它将显示此查询应返回的球员:

http://imgur.com/T8gi368

如您所见,我想要的返回查询应该返回“Ilya Kovalchuk - 37”作为 GoalLeader,“Patrik Elias - 52”作为 AssistLeader,“Ilya Kovalchuk - 83”作为 PointsLeader。运行查询确实提供了这些结果,但包含我不想要的额外信息,如您在此处看到的:

http://imgur.com/UUxM2yA

我的问题是,我如何摆脱多余的信息?我只想要每个类别的领导者,我不想看到排名第二的球员,即使该球员在其他类别中排名第一。本质上,我要说的是,我只想要这张表中的 1 行。以前,我的代码会返回所有玩家,其中领导者位于顶部,所以这段代码离我想要的结果更近了一步,但现在我被卡住了。寻找这个问题的答案一直具有挑战性,因为通常很难找到提出问题的方法。

4

2 回答 2

1

你需要 PIVOT 你的数据,我会使用这样的东西:

SELECT
  MAX(CASE WHEN NJDSkaters.Goals=mx.goals
       THEN CONCAT(PlayerName,' - ', NJDSkaters.Goals) END) GoalLeader,
  MAX(CASE WHEN NJDSkaters.Assists=mx.assists
       THEN CONCAT(PlayerName,' - ', NJDSkaters.Assists) END) AssistsLeader,
  MAX(CASE WHEN NJDSkaters.Points=mx.points
       THEN CONCAT(PlayerName,' - ', NJDSkaters.Points) END) PointsLeader
FROM
  NJDSkaters INNER JOIN (
    SELECT MAX(Goals) goals, MAX(Assists) assists, MAX(Points) points
    FROM NJDSkaters) mx
  ON NJDSkaters.Goals=mx.goals
     OR NJDSkaters.Assists=mx.assists
     OR NJDSkaters.Points=mx.points

在此处查看小提琴。如果多个玩家共享相同的最大值,您可能还想使用 GROUP_CONCAT 而不是 MAX:

SELECT
  CONCAT(GROUP_CONCAT(CASE WHEN  NJDSkaters.Goals=mx.goals
       THEN PlayerName END), ' - ', mx.goals) GoalLeader,
  CONCAT(GROUP_CONCAT(CASE WHEN NJDSkaters.Assists=mx.assists
       THEN PlayerName END), ' - ', mx.assists) AssistsLeader,
  CONCAT(GROUP_CONCAT(CASE WHEN NJDSkaters.Points=mx.points
       THEN PlayerName END), ' - ', mx.points) PointsLeader
FROM
  NJDSkaters INNER JOIN (
    SELECT MAX(Goals) goals, MAX(Assists) assists, MAX(Points) points
    FROM NJDSkaters) mx
  ON NJDSkaters.Goals=mx.goals
     OR NJDSkaters.Assists=mx.assists
     OR NJDSkaters.Points=mx.points

一点解释:

  • 子查询mx将返回最大进球数、最大助攻数和最大得分
  • 我将NJDSkaters使用此子查询加入表以返回具有最大进球数或最大助攻数或最大积分的所有行
  • CASE WHEN NJDSkaters.Goals=mx.goals THEN PlayerName END如果该玩家的进球数达到最大值,则返回PlayerName该值,否则返回 NULL。助攻和得分也是如此。
  • 使用 GROUP_CONCAT 我将 CASE WHEN 返回的所有玩家姓名连接起来。GROUP_CONCAT 将跳过 NULL 值,并且只会连接其类别具有最大值的玩家
  • 使用 CONCAT 我将上面 GROUP_CONCAT 返回的字符串与每个类别的最大值连接起来。
于 2013-04-16T20:19:52.293 回答
0

为什么不使用 LIMIT 1 来限制结果呢?

于 2013-04-16T20:14:51.917 回答