Sql 如何获取每个用户的标志之间经过的时间?

Sql 如何获取每个用户的标志之间经过的时间?,sql,sql-server,sql-server-2008,Sql,Sql Server,Sql Server 2008,下表表示用户登录(即LogAction\u INT=1为登录,LogAction\u INT=0为注销)。将用户登录和注销(会话)之间经过的时间相加的最佳方法是什么。理想情况下,我需要每个用户花费的总时间。我能想到的一切都包括while循环,而且太复杂了 ID User_ID LogDate_DT LogAction_INT 1940 18 2019-04-01 13:15:06.027 1 1941 18 2019-04-01 13:47:39.010 0 1942

下表表示用户登录(即
LogAction\u INT=1
为登录,
LogAction\u INT=0
为注销)。将用户登录和注销(会话)之间经过的时间相加的最佳方法是什么。理想情况下,我需要每个用户花费的总时间。我能想到的一切都包括while循环,而且太复杂了

ID  User_ID LogDate_DT  LogAction_INT
1940    18  2019-04-01 13:15:06.027 1
1941    18  2019-04-01 13:47:39.010 0
1942    18  2019-04-01 15:48:46.453 1
1943    18  2019-04-01 15:54:47.520 0
1944    68  2019-04-02 15:09:20.460 1
1945    68  2019-04-02 15:53:11.223 0
1946    86  2019-04-03 12:48:14.340 1
1947    86  2019-04-03 14:49:55.400 0
1948    80  2019-04-04 08:54:48.157 1
1949    86  2019-04-04 15:26:51.917 1
1950    86  2019-04-04 15:27:53.030 0
1951    86  2019-04-04 15:28:00.920 1
1952    86  2019-04-04 15:28:30.243 0
1953    86  2019-04-04 15:28:35.490 1
1954    86  2019-04-04 15:53:41.700 0
1955    68  2019-04-04 15:54:07.720 1
1956    80  2019-04-04 16:15:55.200 0
我希望有类似于:

User  TotalSessionTime
----  -----------------
18    04:45
68    10:02
80    06:12

如果它总是成对的,您可以使用row_number()生成一个运行的no,然后将每2行分组为1

; with cte as
(
    select *, grp = (row_number() over (partition by User_ID order by ID) - 1) / 2
    from   your_table
)
cte2 as
(
    select  User_ID, elapsed = datediff(second, min(LogDate_DT), max(LogDate_DT))
    from    cte
    group by User_ID, grp
)
select User_ID, sum(elapsed)
from   cte2
group by User_ID

您可以枚举每种类型,然后使用条件聚合或联接:

select user_id, seqnum,
       datediff(second, min(LogDate_DT), max(LogDate_DT)) as diff_seconds
from (select t.*,
             row_number() over (partition by user_id, LogAction_INT order by id) as seqnum
      from t
     ) t
group by user_id, seqnum;
然后,您可以按用户将其相加:

select user_id, sum(diff_seconds)
from (select user_id, seqnum,
             datediff(second, min(LogDate_DT), max(LogDate_DT)) as diff_seconds
      from (select t.*,
                   row_number() over (partition by user_id, LogAction_INT order by id) as seqnum
            from t
           ) t
      group by user_id, seqnum;
     ) t
group by user_id;
这类问题的问题是,输入和输出通常不完全匹配。这使得这个问题变得更加困难


在受支持的SQL Server版本中,我会使用
lag()

您好,欢迎使用SO。您真的在使用sql server 2008吗?如果是这样的话,你应该考虑升级。离生命正式结束只有几个月了。对于手头的问题,您希望示例数据的输出是什么?用户ID 68没有注销值,在这种情况下,我们需要添加任何默认值吗。这是一个很好的回答;我喜欢用一种更简单的方法来计算你所说的
grp