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

Posted

技术标签:

【中文标题】SQL Server - 查询以根据每年的最后一个值计算加权平均值【英文标题】:SQL Server - Query to calculate weighted average based on last values for each year 【发布时间】:2015-11-12 04:22:00 【问题描述】:

假设我有来自美国职棒大联盟投手的 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_ip(投球局)的每个player_idseason_whip 的加权平均值。 我只想使用每年的最后一个条目(注意game_id 列包含年份)。所以对于player_id 502190,2015 年的最后一个条目是game_id2015/08/15/wasmlb-sfnmlb-1,2014 年是game_id2014/09/28/pitmlb-cinmlb-1

加权平均公式为:

sum(season_ip * season_whip) / sum(season_ip)   

所以,比如player_id502190,他的鞭子是

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

我将career_ip 包括在内,因为它是唯一会在所有年份中增加的值。 season_ip 每年重置,season_whip 全年变化。

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

【问题讨论】:

你为什么使用192.1214.1? ...这些不是您的样本数据中的值。在您的数据中,这些是整数 我不明白您为什么包含career_ip,该值不用于计算加权平均值。另外下次尝试提供sqlFiddle,这将有很大帮助。 @JuanCarlosOropeza 我将 192.1 修改为 192 和 214.1 修改为 214 以使其在表格中更加清晰。我忘了修改鞭子计算。我会更新它。谢谢。 【参考方案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

【讨论】:

【参考方案2】:

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

【讨论】:

感谢您的帮助!对于我提供的数据集,此答案在 sqlfiddle 中有效,但由于某种原因,它不适用于我在 SQL 中的完整数据集。我不确定发生了什么事。 Juan Carlos Oropeza 的答案虽然有效,但我会坚持使用那个答案。 @bbgoldm 也许您应该检查或提供更大的样本。因为我们的解决方案几乎相同。

以上是关于SQL Server - 查询以根据每年的最后一个值计算加权平均值的主要内容,如果未能解决你的问题,请参考以下文章

SQL 查询以查找该月的最后一天

SQL Server 查询以根据用户提供的 id 获取嵌套的子记录

SQL 查询以获取每年表现最佳的统计数据(例如 3 个指针)

用于查找下一个欧洲夏令时日期的 SQL Server

Redshift上的SQL查询以获取第一个和最后一个值

循环遍历列表以从 SQL 查询创建多个数据帧