SQL Server - 根据每年的最后值计算加权平均值的查询

时间:2015-08-19 02:57:29

标签: sql sql-server sql-server-2014

假设我在美国职业棒球大联盟投手的SQL表中有以下列:

player_id   game_id             season_ip | season_whip |career_ip

我们有以下数据:

502190  2013/04/18/miamlb-cinmlb-1  19      1.32    504
502190  2013/04/19/miamlb-cinmlb-1  19      1.32    504
502190  2013/06/11/cinmlb-chnmlb-1  73      1.32    558
502190  2013/06/13/cinmlb-chnmlb-1  81      1.24    566
502190  2013/09/29/pitmlb-cinmlb-1  192     1.25    677
502190  2014/04/22/cinmlb-pitmlb-1  28      0.99    705
502190  2014/05/26/cinmlb-lanmlb-1  71      1.06    748
502190  2014/09/28/pitmlb-cinmlb-1  214     1.25    891
502190  2015/03/25/texmlb-cinmlb-1  14      0.71    891
502190  2015/08/15/wasmlb-sfnmlb-1  143     1.17    1034

453286  2013/05/05/detmlb-houmlb-1  39      1.04    844
453286  2013/05/16/detmlb-texmlb-1  54      0.99    859
453286  2013/09/29/detmlb-miamlb-1  214     0.97    1019
453286  2014/06/18/kcamlb-detmlb-1  98      1.25    1117
453286  2014/07/15/nasmlb-aasmlb-1  126     1.17    1145
453286  2014/09/28/minmlb-detmlb-1  220     1.18    1239
453286  2015/03/22/wasmlb-detmlb-1  14      0.93    1239
453286  2015/08/15/wasmlb-sfnmlb-1  165     0.9     1404

我需要一个SQL查询来根据season_whip(投注的局)获得每个player_id season_ip的加权平均值。
我只想使用每年的最后一个条目(注意game_id列包含年份)。因此,对于player_id 502190,2015年的最后一项是game_id 2015/08/15/wasmlb-sfnmlb-1,2014年是game_id 2014/09/28/pitmlb-cinmlb-1

加权平均值的公式为:

sum(season_ip * season_whip) / sum(season_ip)   

所以,例如,player_id 502190,他的鞭子是

[192 * 1.25 + 214 * 1.25 + 143 * 1.17] / [192 + 214 + 143] = 1.229

我加入了career_ip,因为它是唯一一个在这些年中会增加的价值。 season_ip每年重置一次,season_whip全年都有所不同。

感谢任何帮助。我正在使用SQL Server 2014.

2 个答案:

答案 0 :(得分:1)

尝试这样的事情

SQL FIDDLE DEMO

With whip as (
    SELECT *, SUBSTRING(game_id, 1, 4) as year_id
    FROM testMLB
),
year_whip as (
    SELECT *, 
    ROW_NUMBER() OVER (PARTITION BY player_id, year_id ORDER BY game_id DESC) AS RowNumber
    FROM whip
)
SELECT 
    player_id, 
    SUM(season_ip * season_whip) / sum(season_ip) 
FROM year_whip
WHERE RowNumber = 1
GROUP BY player_id

答案 1 :(得分:1)

听起来你想要为每个玩家每年获得最后一行,然后将这些行分组,以便为​​玩家的鞭子获得调整后的权重。如果是这样,您可以使用row_number()在获得加权平均分组之前,每年每位玩家获得最后一行:

  select player_id, sum(season_ip * season_whip) / sum(season_ip) 
  from (
    select * ,
      row_number() over (partition by player_id, left(game_id,4) order by game_id desc) rn 
    from
    mytable
  ) t1 where rn = 1
  group by player_id

http://sqlfiddle.com/#!3/17724/1