需要帮助MySQL查询获得y年和y + 1平均值的结果

时间:2011-02-11 01:50:29

标签: mysql join union

我有一个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的数据等等。

我被困在如何使数据达到平均值并在下一年得到它。

任何人都可以帮助我解决其中一个或两个问题吗?

2 个答案:

答案 0 :(得分: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&gt; = 900。

此外,如果你想首先获得所有玩家的结果,那么总需要你的原始查询并将其与这个结合起来...正如你所看到的,为了保持列与两个查询同步,我'我为玩家和位置设置了一个假的,这样它就不会在不匹配的联盟上崩溃......注意我的COUNT列实际上与ORIGINAL查询的YEAR列相对应。

对于前一年......正如Rob提到的那样,你只需要在两个查询中做一个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,SECOND加入专门针对一个有资格对抗主要玩家的人。最终的列结果使用第二个限定符获得整个第一年限定符,例如

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

答案 1 :(得分:0)

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

将“AVG”应用于“sim”的表达式应该可以在mysql中使用。 e.g。

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)

应该这样做。

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