如何在sql server的select语句中获取参数的最大临时值?

时间:2013-11-25 13:12:38

标签: sql sql-server

如何在sql server的select语句中获取参数的最大临时值? 例: 我有一个表userconnection,其中包含登录和注销时间,如下所示:

action, time, user
Login, 2013-24-11 13:00:00, a
Login, 2013-24-11 13:30:00, b
Login, 2013-24-11 14:00:00, c
Logout, 2013-24-11 14:10:00, b
...
...
...

任何人都可以帮助我查看下面的查询,以显示白天任何时间的最大并发用户数(从上面的示例集中= 3)和当天的当前时间(从上面的示例集中= 2)?

[select DateAdd(day, 0, DateDiff(day, 0, time)) calanderday,
    sum(case when action = 'Login' then 1 when action = 'Logout' then -1
        else 0 end) concurrentuser,
    max of(concurrentuser interim values) maxconcurrentuser
   from userconnection
  where time > sysdate - 1        
group by DateAdd(day, 0, DateDiff(day, 0, time))
order by calanderday] 

我非常感谢任何有关如何获得的帮助 max(concurrentuser临时值)maxconcurrentuser ??在上面的查询中,不使用用户定义的函数等,只使用内联查询。

1 个答案:

答案 0 :(得分:0)

我认为这会有效,但显然你只给我们提供了最少的样本数据:

;With PairedEvents as (
    select a.[user],a.time as timeIn,b.time as TimeOut
    from
        userconnection a
            left join
        userconnection b
            on
                a.[user] = b.[user] and
                a.time < b.time and
                b.action = 'logout'
            left join
        userconnection b_anti
            on
                a.[user] = b_anti.[user] and
                a.time < b_anti.time and
                b_anti.time < b.time and
                b_anti.action = 'logout'
    where
        a.action = 'Login' and
        b_anti.action is null
), PossibleMaxima as (
    select pe.timeIn,COUNT(*) as Cnt
    from
        PairedEvents pe
            inner join
        PairedEvents pe_all
            on
                pe_all.timeIn <= pe.timeIn and
                (
                    pe_all.timeOut > pe.timeIn or
                    pe_all.timeOut is null
                )
    group by pe.timeIn
), Ranked as (
    select *,RANK() OVER (ORDER BY Cnt desc) as rnk
    from PossibleMaxima
)
select * from Ranked where rnk =  1

这假设所有登录事件都可以与注销事件配对,并且您没有杂散的额外内容(没有登录的注销,或者没有注销的情况下连续两次登录)。

它通过生成3 CTEs来工作。第一个,PairedEvents将登录行与其关联的注销行相关联(并且需要上述假设)。

然后,在PossibleMaxima中,我们接受每个登录事件,并尝试查找与该时间重叠的任何PairedEvents行。加入成功的次数是同时在线的用户数。

最后,我们有Ranked CTE给出最大值等级为1.如果有多个句点达到最大值,那么它们将各自排名为1并返回最终结果集。

如果多个用户可以拥有相同的登录时间,则可能需要稍微调整一下PossibleMaxima - 但这只是在我们需要的时候。