username year month day timein time out
xyz 2012 12 05 2012-12-05 08:10:34.500 2012-12-05 11:23:45:508
xyz 2012 12 05 2012-12-05 09:11:14.352 2012-12-05 11:00:45:378
xyz 2012 12 05 2012-12-05 09:50:34.547 2012-12-05 12:23:45:508
xyz 2012 12 05 2012-12-05 12:06:11.119 2012-12-05 01:23:01:290
xyz 2012 12 05 2012-12-05 02:10:34.547 2012-12-05 04:23:45:508
前4行显示重叠会话,最后一行显示非重叠会话。 我需要一个查询来计算该用户的总时间,并显示所有具有计算时间的会话。
答案 0 :(得分:0)
示例数据。
CREATE TABLE Session
([username] varchar(3), [year] int, [month] int, [day] int, [timein] datetime, [timeout] datetime, CHECK([timeout] >= [timein]) )
;
INSERT INTO Session
([username], [year], [month], [day], [timein], [timeout])
VALUES
('xyz', 2012, 12, 05, '2012-12-05 08:10:34', '2012-12-05 11:23:45'),
('xyz', 2012, 12, 05, '2012-12-05 09:11:14', '2012-12-05 11:00:45'),
('xyz', 2012, 12, 05, '2012-12-05 09:50:34', '2012-12-05 12:23:45'),
('xyz', 2012, 12, 05, '2012-12-05 12:06:11', '2012-12-05 13:23:01'),
('xyz', 2012, 12, 05, '2012-12-05 02:10:34', '2012-12-05 04:23:45')
;
当用户的行按timein
排序时,我们知道如果当前行的timein
小于或等于此行所见的timeout
值没有开始新的会议。否则它会启动一个新会话。
WITH T1
AS (SELECT *,
MAX(timeout) OVER (PARTITION BY username ORDER BY timein) AS max_time_out_so_far
FROM Session),
T2
AS (SELECT *,
LAG(max_time_out_so_far) OVER (PARTITION BY username ORDER BY timein) AS prev_max_time_out_so_far
FROM T1),
T3
AS (SELECT *,
SUM(session_start) OVER (PARTITION BY username ORDER BY timein) AS session_group
FROM T2
CROSS APPLY(SELECT CASE WHEN timein <= prev_max_time_out_so_far THEN 0 ELSE 1 END) CA(session_start))
SELECT *
FROM T3
ORDER BY timein
上述样本数据的结果是
+----------+------+-------+-----+-------------------------+-------------------------+-------------------------+--------------------------+---------------+---------------+
| username | year | month | day | timein | timeout | max_time_out_so_far | prev_max_time_out_so_far | session_start | session_group |
+----------+------+-------+-----+-------------------------+-------------------------+-------------------------+--------------------------+---------------+---------------+
| xyz | 2012 | 12 | 5 | 2012-12-05 02:10:34.000 | 2012-12-05 04:23:45.000 | 2012-12-05 04:23:45.000 | NULL | 1 | 1 |
| xyz | 2012 | 12 | 5 | 2012-12-05 08:10:34.000 | 2012-12-05 11:23:45.000 | 2012-12-05 11:23:45.000 | 2012-12-05 04:23:45.000 | 1 | 2 |
| xyz | 2012 | 12 | 5 | 2012-12-05 09:11:14.000 | 2012-12-05 11:00:45.000 | 2012-12-05 11:23:45.000 | 2012-12-05 11:23:45.000 | 0 | 2 |
| xyz | 2012 | 12 | 5 | 2012-12-05 09:50:34.000 | 2012-12-05 12:23:45.000 | 2012-12-05 12:23:45.000 | 2012-12-05 11:23:45.000 | 0 | 2 |
| xyz | 2012 | 12 | 5 | 2012-12-05 12:06:11.000 | 2012-12-05 13:23:01.000 | 2012-12-05 13:23:01.000 | 2012-12-05 12:23:45.000 | 0 | 2 |
+----------+------+-------+-----+-------------------------+-------------------------+-------------------------+--------------------------+---------------+---------------+
session_group
只是到目前为止遇到的session_start
个标记的总计。
这可以在分组查询中使用,如下面的完整示例所示。
WITH T1
AS (SELECT *,
MAX(timeout) OVER (PARTITION BY username ORDER BY timein) AS max_time_out_so_far
FROM Session),
T2
AS (SELECT *,
CASE
WHEN timein <= LAG(max_time_out_so_far) OVER (PARTITION BY username ORDER BY timein)
THEN 0
ELSE 1
END AS session_start
FROM T1),
T3
AS (SELECT *,
SUM(session_start) OVER (PARTITION BY username ORDER BY timein) AS session_group
FROM T2),
T4
AS (SELECT username,
session_group,
MIN(timein) AS timein,
MAX(timeout) AS timeout,
DATEDIFF(SECOND, MIN(timein), MAX(timeout)) AS session_duration
FROM T3
GROUP BY username,
session_group)
SELECT CASE WHEN GROUPING(username) = 0 THEN username ELSE 'TOTAL' END AS username,
session_group,
timein,
timeout,
SUM(session_duration) AS session_duration
FROM T4
GROUP BY GROUPING SETS ( ( username, session_group, timein, timeout ), ( ) )
返回
+----------+---------------+-------------------------+-------------------------+------------------+
| username | session_group | timein | timeout | session_duration |
+----------+---------------+-------------------------+-------------------------+------------------+
| xyz | 1 | 2012-12-05 02:10:34.000 | 2012-12-05 04:23:45.000 | 7991 |
| xyz | 2 | 2012-12-05 08:10:34.000 | 2012-12-05 13:23:01.000 | 18747 |
| TOTAL | NULL | NULL | NULL | 26738 |
+----------+---------------+-------------------------+-------------------------+------------------+