Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby-on-rails-4/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
SQL Server-基于条件的SUM()和Group()记录_Sql_Sql Server_Datetime_Group By_Count - Fatal编程技术网

SQL Server-基于条件的SUM()和Group()记录

SQL Server-基于条件的SUM()和Group()记录,sql,sql-server,datetime,group-by,count,Sql,Sql Server,Datetime,Group By,Count,在我的游戏应用程序中,我有团队,每个团队可以有任意数量的玩家;如果一名球员参加比赛,我会给他5分。每参加一场比赛,他将得到5分加上他的计数 我的存储过程将TeamId作为输入参数 现在我想计算每个队每个月的总参与分数,但是这里每个球员的参与分数应该加到球员参加比赛的最后一个月 比如说,Team1有Player1和Player1总共打了4场比赛,2020年4月1场,2020年6月2场,2020年8月1场,在这里进行的4场比赛中,Team1的Player1获得了20个参与点,而最后一场比赛的Play

在我的游戏应用程序中,我有团队,每个团队可以有任意数量的玩家;如果一名球员参加比赛,我会给他5分。每参加一场比赛,他将得到5分加上他的计数

我的存储过程将
TeamId
作为输入参数

现在我想计算每个队每个月的总参与分数,但是这里每个球员的参与分数应该加到球员参加比赛的最后一个月

比如说,
Team1
Player1
Player1
总共打了4场比赛,2020年4月1场,2020年6月2场,2020年8月1场,在这里进行的4场比赛中,
Team1的
Player1
获得了20个参与点,而最后一场比赛的Player1是在2020年8月进行的,因此所有这20个点都应添加到2020年8月的Team1中

在每位玩家的玩家表中,我有每位玩家的[TotalMatchesPlayed],[TotalMatchesPlayed]*5将给出每位玩家的[TotalParticipationPoints]

这应该对团队中的所有球员重复

    SELECT SUM(ISNULL(P.[TotalMatchesPlayed], 0) * 5) AS [ParticipationPoints], CAST(MONTH(PA.[ActivityDate]) AS VARCHAR(2)) AS [Month], CAST(YEAR(PA.[ActivityDate]) AS VARCHAR(4)) AS [Year] FROM [TeamPlayer] TP
INNER JOIN dbo.[Player] P
ON TP.[PlayerId] = P.[PlayerId]
INNER JOIN dbo.[PlayerActivity] PA
ON PA.[PlayerId] = P.[PlayerId] AND PA.[PlayerActivityTyepId] = 14
WHERE TP.[TeamId] = 45
GROUP BY CAST(MONTH(PA.[ActivityDate]) AS VARCHAR(2)), CAST(YEAR(PA.[ActivityDate]) AS VARCHAR(4))
我对这个查询的问题是,[PlayerActivity]表在球员每次参加比赛时都有一行,现在我只想获取最新的日期,并将我无法实现的所有参与点添加到该月份和年份中

我的示例输出应该如下所示

ParticipationPoints | Month |  Year
        5                06     2020
       10                11     2020

创建表格团队成员(
TeamPlayerID int,
PlayerId int,
TeamId INT
);
插入到TeamPlayer值中(1、101、45)
插入到TeamPlayer值中(2、104、19)
插入TeamPlayer值(3、108、45)
创建桌面播放器(
PlayerID int,
名字VARCHAR(1000),
姓氏VARCHAR(1000),
[TotalMatchesPlayed]整数
);
插入玩家值(101,'Joe','Abbey',2)
插入玩家值(102,'Vince','Abbott',3)
插入玩家值(103,'Duke','Abbruzzi',7)
插入玩家值(104,'Kamlesh','Abu',9)
插入玩家值(105,'Evika','Abram',0)
插入玩家值(106,'王子','微妙',2)
插入玩家值(107,'Dick','Absher',1)
插入玩家值(108,'George','Abrell',1)
插入玩家值(109,'William','Peck',2)
插入玩家值(110,'Aaron','Adams',0)
创建表格播放活动(
PlayerActivityId int,
PlayerId int,
playerActivityTypid INT,
活动日期
);
插入到PlayerActivity值中(10114,'2020-04-21')
插入到PlayerActivity值中(210814,'2020-06-17')
插入到PlayerActivity值中(3、101、14、'2020-11-24')
下面链接中的示例表设计和示例数据与我的查询有关


再次重申,如果一个队中的球员打了多场比赛,比如说6场,我需要在他最后一场比赛的月份加上6*5=30分。

我的解决方案使用一个子查询来确定每个球员的最后活动日期

选择
PlayerId,
最大(活动日期)为最后日期
从…起
dbo.PlayerActivity
其中playerActivityTypid=14
按PlayerId分组
主查询还使用GROUP BY来聚合每个团队和年/月的结果。这个技巧是在CASE表达式中完成的。这里,我将实际活动日期与子查询确定的最后一个活动日期进行比较。这些点仅在最后一个活动中获得属性,否则为0

选择
TP.TeamId,
总数(
案例
当PA.ActivityDate=X.LastDate时
然后P.TotalMatchesPlayed*5
其他0
结束
)作为参与点,
右(将(100个月以上(PA.ActivityDate)转换为VARCHAR(3)),2)转换为[月],
将(年(PA.ActivityDate)转换为VARCHAR(4))转换为[年]
从…起
dbo.TeamPlayer TP
内部连接dbo.P
在TP.PlayerId=P.PlayerId上
内部连接dbo.PlayerActivity PA
在PA.PlayerId=P.PlayerId和PA.playerActivityTypid=14上
内连接(
挑选
PlayerId,
最大(活动日期)为最后日期
从…起
dbo.PlayerActivity
其中playerActivityTypid=14
按PlayerId分组
)AS X
在X.PlayerId=P.PlayerId上
其中TP.TeamId=45
分组
TP.TeamId,年(PA.ActivityDate),月(PA.ActivityDate)

请注意,我假设每个玩家每天只有一项活动。如果有更多,则会反复总结要点。如果严格按照升序插入
PlayerActivityId
值,可以通过使用
MAX(PlayerActivityId)
而不是
MAX(ActivityDate)
来解决此问题


要获得两位数的月份,我首先计算月份+100,并将其转换为
VARCHAR(3)
。这将产生4月份的
'104'
。然后使用
RIGHT
函数返回最后两个字符,得到结果。当然,您可以使用适当的格式化函数,但我懒得查找要使用的正确函数和格式。

我的解决方案使用一个子查询来确定每个播放器的最后活动日期

选择
PlayerId,
最大(活动日期)为最后日期
从…起
dbo.PlayerActivity
其中playerActivityTypid=14
按PlayerId分组
主查询还使用GROUP BY来聚合每个团队和年/月的结果。这个技巧是在CASE表达式中完成的。这里,我将实际活动日期与子查询确定的最后一个活动日期进行比较。这些点仅在最后一个活动中获得属性,否则为0

选择
TP.TeamId,
总数(
案例
当PA.ActivityDate=X.LastDate时
然后P.TotalMatchesPlayed*5
其他0
结束
)作为参与点,
右(将(100个月以上(PA.ActivityDate)转换为VARCHAR(3)),2)转换为[月],
将(年(PA.ActivityDate)转换为VARCHAR(4))转换为[年]
从…起
dbo.TeamPlayer TP
内连接dbo
select year(activitydate) as yyyy, month(activitydate) as mm, 
    sum(cnt) * 5 as partitionpoints
from (
    select pa.*, 
        count(*) over(partition by playerid) cnt,
        row_number() over(partition by playerid order by activitydate desc) rn
    from playeractivity pa
) t
where rn = 1
group by year(activitydate), month(activitydate)
order by yyyy, mm
yyyy | mm | partitionpoints ---: | -: | --------------: 2020 | 6 | 5 2020 | 11 | 10