You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

求助:使用Window Function计算玩家胜率返回全零的问题

问题描述

我有一个小型数据集:

Player 1    W
Player 1    L
Player 1    L
Player 1    W
Player 1    W
Player 2    L
Player 2    L
Player 2    W

我尝试使用窗口函数计算玩家的胜率,期望得到如下结果:

Player 1 60%
Player 2 33%

但我编写的SQL语句返回全零,代码如下:

create table #t1 (
    player_name varchar(10)
    , win_loss char(1)
)

insert into #t1
values 
('Player 1','W')
,('Player 1','L')
,('Player 1','L')
,('Player 1','W')
,('Player 1','W')
,('Player 2','L')
,('Player 2','L')
,('Player 2','W')

select 
    sum(case when win_loss = 'W' then 1 else 0 end) over (partition by player_name)
    / count(player_name) over (partition by player_name)
from #t1
问题原因与解决方法

原因分析

返回全零是整数除法导致的:SQL中两个整数相除时会自动舍弃小数部分,只保留整数结果。比如Player 1胜场3、总场次5,3/5在整数除法里结果为0,而非0.6。另外,原查询会为每个玩家的每一行都返回相同的胜率值,无法直接得到期望的“每个玩家一行”的结果。

解决方法

方法1:分组聚合(推荐,更简洁)

用GROUP BY分组计算,同时通过强制转换数据类型避免整数除法:

select 
    player_name,
    cast(sum(case when win_loss = 'W' then 1 else 0 end) * 100.0 / count(*) as decimal(5,1)) || '%' as win_rate
from #t1
group by player_name

方法2:修正窗口函数查询

如果必须使用窗口函数,需将其中一个操作数转为浮点型,同时用DISTINCT去重得到每个玩家唯一的胜率:

select distinct
    player_name,
    cast(
        sum(case when win_loss = 'W' then 1.0 else 0 end) over (partition by player_name)
        / count(player_name) over (partition by player_name) * 100
        as decimal(5,1)
    ) || '%' as win_rate
from #t1

补充说明

  • 把1改成1.0或者乘以100.0,是为了让运算转为浮点型,保留小数部分。
  • cast(...) as decimal(5,1)用来将结果格式化为一位小数,和期望的60%、33%匹配;如果需要整数百分比,可调整为decimal(3,0)。

内容的提问来源于stack exchange,提问作者Jason

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 09:36:26