使用列的 min/max 创建 SQL 视图

Create SQL view using min/max of column

我有一个 table 存储游戏 ID 列表、玩该游戏的用户的用户 ID 以及每个用户在游戏中获得的分数,如下所示:

GameID     UserID     Score
1          Bob        12
1          Sally      14
2          Bob        17
2          Jane       17
3          Sally      16
3          Jane       10
3          Trish      10

我正在尝试编写一个 SQL 查询来创建此数据的视图,根据得分告诉我每个用户赢了多少场、平了多少场和输了多少场。所以视图如下所示:

UserId     NumWins     NumLosses     NumDraws
Bob        0           1             1
Sally      2           0             0
Jane       0           1             1
Trish      0           1             0

我正在尝试想出语法来创建以这种方式转换数据的视图,但遇到了问题。

可以使用RANK()window函数和条件聚合:

with
  ranks as (
    select *, rank() over (partition by gameid order by score desc) rnk
  from tablename
  ),
  cte as (
    select *, count(*) over (partition by gameid, rnk) counter
    from ranks
  )
select userid,
  sum(case when rnk = 1 and counter = 1 then 1 else 0 end) NumWins,          
  sum(case when rnk > 1 then 1 else 0 end) NumLosses,
  sum(case when rnk = 1 and counter > 1 then 1 else 0 end) NumDraws
from cte  
group by userid

参见demo
结果:

> userid | NumWins | NumLosses | NumDraws
> :----- | ------: | --------: | -------:
> Bob    |       0 |         1 |        1
> Jane   |       0 |         1 |        1
> Sally  |       2 |         0 |        0
> Trish  |       0 |         1 |        0

您可以使用如下条件聚合

SELECT * INTO Games
FROM
(
  VALUES
  (1, 'Bob',     12),
  (1, 'Sally',     14),
  (2, 'Bob',     17),
  (2, 'Jane',     17),
  (3, 'Sally',     16),
  (3, 'Jane',     10),
  (3, 'Trish',     10)
) T(GameId, UserId, Score);

SELECT G.UserId,
       SUM(CASE WHEN MXS = Score AND MNS <> Score THEN 1 ELSE 0 END) Wins,
       SUM(CASE WHEN MXS > Score AND Score = MNS THEN 1 ELSE 0 END) Loses,
       SUM(CASE WHEN MXS = MNS THEN 1 ELSE 0 END) Draws
FROM Games G
JOIN 
(
  SELECT GameId, MAX(Score) MXS, MIN(Score) MNS
  FROM Games
  GROUP BY GameId
) T(GameId, MXS, MNS) 
ON G.GameId = T.GameId
GROUP BY UserId

这是一个db<>fiddle