Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/24.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 将起始触发器和结束触发器之间的行分组_Sql_Sql Server_Tsql - Fatal编程技术网

Sql 将起始触发器和结束触发器之间的行分组

Sql 将起始触发器和结束触发器之间的行分组,sql,sql-server,tsql,Sql,Sql Server,Tsql,如果你能帮我解决问题,那就太好了。我有一张桌子,在那里你可以看到比赛中的事件。每个玩家都有一定数量的金币,登录后可以在值列中看到。我需要了解人们在登录后开始玩第一个游戏的金币数量。在玩家开始游戏之前,他们可以购买黄金或获得奖金,这将提高他们的黄金价值 我想要的结果就是这样。它基本上是开始游戏和玩家最近登录之间的值的总和 **Match number Player ID Value** 1 1111 650 2

如果你能帮我解决问题,那就太好了。我有一张桌子,在那里你可以看到比赛中的事件。每个玩家都有一定数量的金币,登录后可以在值列中看到。我需要了解人们在登录后开始玩第一个游戏的金币数量。在玩家开始游戏之前,他们可以购买黄金或获得奖金,这将提高他们的黄金价值

我想要的结果就是这样。它基本上是开始游戏和玩家最近登录之间的值的总和

**Match number   Player ID     Value**
     1             1111         650
     2             3333         750
     3             1111         400
     4             2222         450

谢谢大家!

您可以尝试一些相关子查询:

SELECT PlayerID, SUM(value) FROM table a
WHERE
TimeStamp >= (SELECT MAX(TimeStamp) FROM table WHERE a.PlayerID = PlayerID AND Action = 'Log in' )
GROUP BY PlayerID

这有点复杂。我的方法是,为每个登录找到下一个时间戳,这是一个登录或开始游戏,然后连接回原始表以查找所有黄金条目

select tli.playerId, tli.TimeStamp, sum(value)
from (select t.*,
             (select top 1 timestamp
              from t t2
              where t2.playerId = t.playerId and
                    t2.timestamp > t.timestamp and
                    t2.action in ('log in', 'start game')
              order by timestamp
             ) as nextTimestamp
      from t
      where t.action in ('log in')
     ) tli join
     t
     on t.playerId = tli.playerId and
        t.timestamp >= tli.timestamp and
        t.timestamp < tli.nextTimeStamp
group by tli.playerId, tli.timeStamp

一种方法是搜索每一行中的日志。然后查找下一行,即登录或开始游戏。如果该行是开始游戏,则有一对用于标识登录后的第一个游戏。然后可以找到该对之间所有行的值之和:

select  row_number() over (order by start.Timestamp) as MatchNumber
,       start.[Player ID]
,       vals.SumValue
from    YourTable login
cross apply
        (
        select  top 1 *
        from    YourTable start
        where   login.[Player ID] = start.[Player ID]
                and login.Timestamp < start.Timestamp 
                and start.Action in ('Start game', 'Log in')
        order by
                start.Timestamp
        ) start
cross apply
        (
        select  sum(cast(vals.Value as int)) as SumValue
        from    YourTable vals
        where   vals.[Player ID] = start.[Player ID]
                and vals.Action in ('Log in', 'Get bonus', 'Buy gold')
                and vals.Timestamp between login.Timestamp and start.Timestamp
        ) vals
where   login.Action = 'Log in'
        and start.Action = 'Start game'

匹配号是你的基本表中的一个字段吗?@Gorionovic。你在这两段话里说了两件不同的事。第一段说,我需要知道人们在登录后第一次玩游戏的黄金数量。第二种说法是,它基本上是开始游戏和玩家最近登录之间的值的总和。我认为示例数据与第一个定义更为一致,但您能否解决这个问题以澄清您的意思?SQL Server的哪个版本?请添加相应的标记。具有top的子查询需要order by。这也超过了两次登录后一次开始游戏的总和。仍然超过了应有的总和,请参阅@Andomar中的玩家2222。我一定错过了什么。对于玩家2222,800、700和450的值看起来是正确的。只有登录后的第一个游戏才算。看看问题中的示例输出。示例数据清楚地显示了1111的两行,因此按PlayerId分组似乎不是正确的解决方案。非常有用!非常感谢。
select  row_number() over (order by start.Timestamp) as MatchNumber
,       start.[Player ID]
,       vals.SumValue
from    YourTable login
cross apply
        (
        select  top 1 *
        from    YourTable start
        where   login.[Player ID] = start.[Player ID]
                and login.Timestamp < start.Timestamp 
                and start.Action in ('Start game', 'Log in')
        order by
                start.Timestamp
        ) start
cross apply
        (
        select  sum(cast(vals.Value as int)) as SumValue
        from    YourTable vals
        where   vals.[Player ID] = start.[Player ID]
                and vals.Action in ('Log in', 'Get bonus', 'Buy gold')
                and vals.Timestamp between login.Timestamp and start.Timestamp
        ) vals
where   login.Action = 'Log in'
        and start.Action = 'Start game'