【问题标题】:Need help with MySQL query getting results to average for year y and y+1需要有关 MySQL 查询的帮助,以获取 y 年和 y+1 年的平均结果
【发布时间】:2011-02-11 01:50:29
【问题描述】:

我有一个 MySQL 查询:

SELECT px.player, px.pos, px.year, px.age, px.gp, px.goals, px.assists
    , 1000 - ABS(p1.gp - px.gp) - ABS(p1.goals - px.goals) - ABS(p1.assists - px.assists) sim
 FROM hockey p1
 JOIN hockey px
   ON px.player <> p1.player
 WHERE p1.player = 'John Smith'
  AND p1.year = 2010
  HAVING sim >= 900
  ORDER BY sim DESC

这给我一个结果表,如下所示:

player  pos year    age gp  goals   assists sim
Player1 LW  2002    25  75  29  32  961
Player2 LW  2000    27  82  29  27  956
Player3 RW  2000    27  78  29  33  955
Player4 LW  2009    26  82  30  30  940
Player5 RW  2001    25  79  33  24  938
Player6 LW  2008    25  82  23  24  936
Player7 LW  2006    27  79  26  33  932

相反,我希望它做两件事。平均数据并添加玩家数量,所以我得到如下内容:

players age gp  goals   assists sim
7   26  79  28  29  945

我尝试了 avg(px.age)、avg(px.gp)、avg(px.goals)...等,但我的“sim”公式遇到了错误。

第二个问题是,在此之下,我想获得下一年数据的平均值。换句话说,2003 年 Player1 的数据,2001 年 Player2 的数据,等等。

我不知道如何将数据平均化并在下一年获得它。

谁能帮助我解决这些问题中的一个或两个?

【问题讨论】:

  • 您能否转储一些曲棍球桌让我显示不同的“球员”和他们各自的年份...您的查询似乎是“比较约翰史密斯 2010 年的活动”与所有其他球员...然后,您想根据 OTHER PLAYER 明年的统计数据将他在 2010 年的活动与其他球员的统计数据进行比较...所以,显示 John Smith 与 Player 2 的 2000 年数据,然后是 Player 2 的 2001 年数据,然后再次显示 John Smith 与 Player 6 的 2008 年数据然后想要 2009 年的统计数据...这是您要找的吗?

标签: mysql join union


【解决方案1】:

要获得计数和平均值的单个小计,只需将原始查询包装为内部选择...类似于...(pq = "PreQuery" 选择结果)

Select 
      max( "Tot Players" ) Players,
      max( "->" ) position,
      count(*) Year,
      avg( pq.age ) AvgAge,
      avg( pq.gp ) AvgGP,
      avg( pq.goals ) AvgGoals,
      avg( pq.assists ) AvgAssists,
      avg( pq.sim ) AvgSim
   from 
      ( SELECT 
             px.player, 
             px.pos, 
             px.year, 
             px.age, 
             px.gp, 
             px.goals, 
             px.assists,
             1000 - ABS(p1.gp - px.gp) 
                  - ABS(p1.goals - px.goals) 
                  - ABS(p1.assists - px.assists) sim  
          FROM 
             hockey p1
                JOIN hockey px ON px.player <> p1.player  
          WHERE 
                 p1.player = 'John Smith'   
             AND p1.year = 2010   
          HAVING 
             sim >= 900
          ORDER BY 
             sim DESC ) pq

如果您的原始查询有效,这应该会为您提供总体平均值。但是,使用具有和顺序的 INNER 查询可能会导致问题。您可能需要取消订单,因为它在最外面的查询中确实没有区别。至于 INNER 查询中的 HAVING 子句,可能需要移到 OUTER SQL-Select 中的 WHERE pq.sim >= 900。

此外,如果您首先想要所有玩家的结果,然后是总数,请获取您的原始查询并将其与这个查询合并...如您所见,为了使列与两个查询保持同步,我'我为玩家和位置添加了一个虚假信息,因此它不会在不匹配的联合中崩溃...请注意,我的 COUNT 列实际上与 ORIGINAL 查询的 YEAR 列相对应。

对于前一年...正如 Rob 所说,您只需对两个查询进行 UNION 即可显示您在每个 UNION 中符合资格的相应年份...

编辑---第二年的澄清......

根据您随后的评论澄清,您必须将基础作为年份 +1 的基础...如果您随后再次想要整体平均值,则这些平均值将被包装到外部最大值/平均值等。 . 但我认为这就是你接下来一年每位球员想要的结果

SELECT
      PrimaryQry.PrimaryPlayer,
      PrimaryQry.PrimaryPos,
      PrimaryQry.PrimaryYear,
      PrimaryQry.PrimaryAge,
      PrimaryQry.PrimaryGP,
      PrimaryQry.PrimaryGoals,
      PrimaryQry.PrimaryAssists,
      PrimaryQry.player,
      PrimaryQry.pos,
      PrimaryQry.year,
      PrimaryQry.age,
      PrimaryQry.gp,
      PrimaryQry.goals,
      PrimaryQry.assists,
      PrimaryQry.sim,
      p2.pos  PrimaryPos2,
      p2.year PrimaryYear2,
      p2.age  PrimaryAge2,
      p2.gp   PrimaryGP2,
      p2.goals PrimaryGoals2,
      p2.assists PrimaryAssists2,
      px2.player player2,
      px2.pos pos2,
      px2.year year2,
      px2.age age2,
      px2.gp gp2,
      px2.goals goals2,
      px2.assists assists2,
      1000 - ABS(p2.gp - px2.gp)
           - ABS(p2.goals - px2.goals)
           - ABS(p2.assists - px2.assists) sim2
  FROM
      ( SELECT
             p1.player PrimaryPlayer,
             p1.pos PrimaryPos,
             p1.year PrimaryYear,
             p1.age PrimaryAge,
             p1.gp PrimaryGP,
             p1.goals PrimaryGoals,
             p1.assists PrimaryAssists,
             px.player,
             px.pos,
             px.year,
             px.age,
             px.gp,
             px.goals,
             px.assists,
             1000 - ABS(p1.gp - px.gp)
                  - ABS(p1.goals - px.goals)
                  - ABS(p1.assists - px.assists) sim             
         FROM
             hockey p1
               JOIN hockey px 
                  ON p1.player <> px.player
         WHERE
                 p1.player = 'John Smith'
             AND p1.year = 2010
         HAVING
             sim >= 900 ) PrimaryQry
         JOIN hockey p2
             ON PrimaryQry.PrimaryPlayer = p2.player
            AND PrimaryQry.PrimaryYear +1 = p2.year
         JOIN hockey px2
             ON PrimaryQry.Player = px2.Player
            AND PrimaryQry.Year +1 = px2.year

如果您按照这里的逻辑,您已经知道内部查询返回了大约 10 个其他玩家。因此,我也在该查询中保留了第一人称基础的统计信息。然后,我将结果集加入曲棍球桌 TWICE ... 加入是主要玩家加入第一个他/她的年份 +1,第二个加入专门针对有资格对抗主要球员的人。最后一列结果得到整个第一年的限定词和第二个限定词,比如

So, it will all be on one row consecutively of 
John Smith 2010   Compare Person 1 YearA  John Smith 2011   Compare Person 1 YearA+1
John Smith 2010   Compare Person 2 YearB  John Smith 2011   Compare Person 2 YearB+1
John Smith 2010   Compare Person 3 YearC  John Smith 2011   Compare Person 3 YearC+1

【讨论】:

  • 优秀。谢谢你!今晚我会试一试,让你知道我的发现。假设这可行,那么我是否会在最后(在 'sim DESC ) pq" 之后)加上“WHERE pq.year = px.year +1”以获取下一年类似玩家的统计数据?
  • @NeilG,我已经编辑以澄清联合...如果这不是您所期望的,请告诉我。
  • 感谢您的澄清,但事实并非如此。我知道这很令人困惑,但我需要他们明年的球员统计数据,而不是我们最初与之比较的球员的年份。因此,我们正在寻找与 JSmith 相似的玩家在同一年的表现如何,然后是他们明年(y+1)。所以回到我的示例输出,Player1 在 2003 年的统计数据,因为他在 2002 年很相似。我想看看他在第二年的表现如何,对 Players1...n 也是如此。那有意义吗?再次感谢您的帮助。
  • @NeilG,检查更新...然后您可以按照我认为您想要的那样将其作为全年/下一年的 MAX 和 AVG 的基础。
  • 再次感谢。我加载它并得到第 54 行的错误消息:JOIN hockey px ON p1.player px.player WHERE
【解决方案2】:

您使用什么查询来获取平均值?

只需将“AVG”应用于“sim”的表达式即可在 mysql 中工作。例如

AVG(1000 - ABS(p1.gp - px.gp) - ABS(p1.goals - px.goals) - ABS(p1.assists - px.assists)) sim

要汇总不同年份的数据,我认为除了使用子选择或联合之外别无选择。

参考:

类似:

(ORIGINAL AVG QUERY) 
UNION ALL 
(ORIGINAL AVG QUERY WITH NEW YEAR)

应该可以解决问题。

(请注意,您的原始查询会选择每年的数据,以将其与 John Smith 在 2010 年的数据进行比较,这可能不是您想要的。)

【讨论】:

  • 谢谢,但这不起作用。如果有意义的话,我需要不要对“sim”进行平均,但要对统计数据(gp、进球、助攻)的结果进行平均。也许我需要不止一步地做到这一点?例如,计算“sim”然后获取匹配的数据?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-04-18
  • 2011-06-30
  • 2011-04-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多