我如何获得每个用户的标志之间经过的时间?
How do I get the time elapsed between flags for every user?
下面的table表示用户登录(即LogAction_INT = 1
为登录,LogAction_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 服务器的受支持版本中,我将使用 lag()
来执行此操作。
下面的table表示用户登录(即LogAction_INT = 1
为登录,LogAction_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 服务器的受支持版本中,我将使用 lag()
来执行此操作。