EAV将数据设置为基于集合的聚合结果

时间:2013-05-06 20:24:28

标签: sql sql-server sql-server-2008 tsql aggregate

我有用户登录应用程序时生成的数据。它包含带时间戳的登录和注销,不会归因于任何特定的工作广告系列。这些是我对每条记录的界限。

在该时间范围内,我有可重复的操作,任务1,任务2,休息等,这些操作都归因于广告系列。

为了开始处理其他广告系列,用户必须注销并重新启动该应用程序,这将重新启动该过程。

在这个小提琴中,我已经列出了表格和样本数据,并且我第一次尝试收集数据,但是使用这种方法,登录/注销的开始和停止时间总和在一起,但是我需要数据来反映广告系列的开始和停止时间,我对此感到失望。

http://sqlfiddle.com/#!3/5347c/1

我的结果需要包括:

  • 运动
  • 始发
  • 开始(该套装的登录操作时间)
  • 结束(该套装的退出操作的时间)
  • 集合
  • 的任务1总和
  • 集合
  • 的任务2的总和
  • 该集的最后一项任务

    ══════════════════════════════════════════════════
    Campaign Originator Start End   Task1 Task2 LastAction
    ═══════════════════════════════════════════════════
    Camp1    1000       08:00 09:27 3120  855    Logout   
    Camp2    1000       09:30 10:32 1800  135    Logout   
    Camp1    1000       13:00 0        0         Task1    
    

我尝试过将CTE方法作为单独行进行登录和注销时间,但后来由于我不确定下一步,我自己陷入了混乱的圈子。

有人可以分享一下如何实现这些结果的想法吗?

1 个答案:

答案 0 :(得分:1)

这可能需要一些重构:

;with Sessions as (
    select OriginatorId, State, Duration, ActionLocalTime, Campaign
        -- Get an id that will later be used to find the max row per session. Break ties with logical State order.
        , row_number() over (order by OriginatorId, ActionLocalTime, case State when 'Login' then 10 when 'Logout' then 30 else 20 end, State) as RowNum
        -- Get a Session id for each login
        , (select count(*) from Actions where State = 'Login' and OriginatorID = a.OriginatorID and ActionLocalTime <= a.ActionLocalTime) as Session
    from Actions a
), Campaigns as (
    select OriginatorId, State, Duration, ActionLocalTime, RowNum
        -- Get the Campaign for this session
        , (select max(Campaign) from Sessions where OriginatorID = s.OriginatorID and Session = s.Session) as Campaign
    from Sessions s
)
select Campaign
    , OriginatorID as Originator
    , min(ActionLocalTime) as Start
    , (select ActionLocalTime from Sessions where RowNum = max(c.RowNum) and State = 'Logout') as [End]
    , (select sum(Duration) from Campaigns where OriginatorID = c.OriginatorID and Campaign = c.Campaign and State = 'Task 1') as Task1
    , (select sum(Duration) from Campaigns where OriginatorID = c.OriginatorID and Campaign = c.Campaign and State = 'Task 2') as Task2
    , (select State from Sessions where RowNum = max(c.RowNum)) as LastAction
from Campaigns c
group by OriginatorID, Campaign
order by OriginatorID, Campaign

输出:

Campaign Originator Start                   End                     Task1 Task2 LastAction
-------- ---------- ----------------------- ----------------------- ----- ----- ----------
Camp1    1000       2013-05-06 08:00:00.000 2013-05-06 09:27:00.000 3120  855   Logout
Camp2    1000       2013-05-06 09:30:00.000 2013-05-06 10:32:00.000 1800  135   Logout

这是SQL Fiddle,其中包含一些额外的数据。