使用列的 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
我有一个 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