SQL 服务器 - 查询以根据每年的最后一个值计算加权平均值

SQL Server - Query to calculate weighted average based on last values for each year

假设我有来自美国职业棒球大联盟投手的 SQL table 的以下列:

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 查询来获取每个 player_idseason_whip 的加权平均值,基于 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。

尝试这样的事情

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

听起来您想获取每个玩家每年的最后一行,然后将这些行分组以获得玩家鞭子的调整权重。如果是这样,您可以使用 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