在开始触发和完成触发之间的GROUP行

时间:2013-03-24 12:56:53

标签: sql sql-server tsql

如果你可以帮我解决我的问题会很酷。我有一张桌子,你可以看到游戏中的事件。每位玩家都有一些黄金,您可以在Value之后的Log in列中查看。我需要了解在Log in之后有多少金人开始玩第一场比赛。在玩家开始游戏之前,他们可以Buy goldGet bonusValue

提高金额
**Player ID      Timestamp      Action     Value**    
    1111           09:11        Log in      500
    1111           09:25        Buy gold    100
    1111           09:28        Get bonus    50
    1111           09:30        Start game      
    2222           11:14        Log in      800
    3333           12:01        Log in      700
    3333           12:04        Get bonus    50
    3333           12:08        Start game   
    3333           12:15        Buy gold    100
    3333           12:18        Start game
    1111           14:40        Log in      300
    1111           14:42        Buy gold    100
    1111           14:50        Start game
    2222           15:22        Log in      600
    2222           15:25        Buy gold    100
    2222           16:25        Log in      400
    2222           16:30        Get bonus    50
    2222           16:35        Start game     

我正在寻找的结果是这样的。它基本上是Start game与玩家最近Log in之间的值的和。

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

谢谢!

3 个答案:

答案 0 :(得分:1)

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

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

答案 1 :(得分:1)

一种方法是搜索每个Log in行。然后查找下一行Log inStart game。如果该行是Start game,则您有一对标识登录后的第一个游戏。然后,您可以找到该对之间所有行的值的总和:

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'

Example at SQL Fiddle.

答案 2 :(得分:0)

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

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