我想生成一个查询,输出一天中某些时间之间的并发用户数。我将使用变量来允许我选择特定的一天。
该表有一个login_time字段,它是datetime,还有一个logout_time字段,也是datetime。基本上,如果用户在该小时内的任何时间点登录,我希望能够输出到一小时列。
案例陈述不可扩展,所以如果我想减少到十五分钟而不是一小时,我实际上需要48个案例陈述。
有没有更好的方法来处理这样的查询以输出并发用户登录?很高兴能够在MSBI堆栈中的任何地方提供解决方案。
答案 0 :(得分:1)
这里是一种在白天获得定义长度的时间段的方法,然后您可以在查询中加入或交叉应用或以其他方式使用TIMESLOTS CTE来汇总这些插槽中的数据 - 在您的情况下,时间段长度将为60
DECLARE @SLOTMINS AS INTEGER;
SET @SLOTMINS = 15;
;with TIMESLOTS AS
(SELECT CAST('00:00' as datetime) as start, 0 as mins
UNION ALL
SELECT dateadd(n, @SLOTMINS, TIMESLOTS.start), mins + @SLOTMINS from TIMESLOTS WHERE mins + @SLOTMINS < 1440
)
select * from TIMESLOTS
答案 1 :(得分:1)
如果你已经设定了你正在进行查询的时间(例如最短的是15分钟),那么你可以创建一个日期表来链接,而不是在运行中计算它。
假设我们有这个样本数据;
CREATE TABLE #TestData (loginID int, login_time datetime, logout_time datetime)
INSERT INTO #TestData (loginID, login_time, logout_time)
VALUES
('1','2016-06-08 09:10:00','2016-06-08 10:10:00')
,('2','2016-06-08 08:55:00','2016-06-08 10:55:00')
,('3','2016-06-08 09:29:00','2016-06-08 10:29:00')
,('4','2016-06-08 09:40:00','2016-06-08 10:40:00')
,('5','2016-06-08 09:08:00','2016-06-08 10:08:00')
,('6','2016-06-08 09:04:00','2016-06-08 10:04:00')
,('7','2016-06-08 09:12:00','2016-06-08 10:12:00')
,('8','2016-06-08 09:40:00','2016-06-08 10:40:00')
,('9','2016-06-08 09:21:00','2016-06-08 10:21:00')
你可以像这样创建一个日期表(这个例子是一个非常简化的版本);
CREATE TABLE #DateTimeTable (ReferenceDate datetime, RefHour datetime)
INSERT INTO #DateTimeTable
VALUES
('2016-06-08 08:45:00','2016-06-08 08:00:00')
,('2016-06-08 09:00:00','2016-06-08 09:00:00')
,('2016-06-08 09:15:00','2016-06-08 09:00:00')
,('2016-06-08 09:30:00','2016-06-08 09:00:00')
,('2016-06-08 09:45:00','2016-06-08 09:00:00')
,('2016-06-08 10:00:00','2016-06-08 10:00:00')
,('2016-06-08 10:15:00','2016-06-08 10:00:00')
,('2016-06-08 10:30:00','2016-06-08 10:00:00')
然后,如果您希望每15分钟为用户提供一次结果,则可以使用此查询;
SELECT
dtt.ReferenceDate
,COUNT(td.loginID) Users
FROM #TestData td
CROSS JOIN #DateTimeTable dtt
WHERE td.login_time <= dtt.ReferenceDate
AND td.logout_time > dtt.ReferenceDate
GROUP BY dtt.ReferenceDate
这给出了这个结果;
ReferenceDate Users
2016-06-08 09:00:00.000 1
2016-06-08 09:15:00.000 5
2016-06-08 09:30:00.000 7
2016-06-08 09:45:00.000 9
2016-06-08 10:00:00.000 9
2016-06-08 10:15:00.000 5
2016-06-08 10:30:00.000 3
如果你想要按小时计算,那么就可以使用这个;
SELECT
dtt.RefHour
,COUNT(td.loginID) Users
FROM #TestData td
CROSS JOIN (SELECT DISTINCT RefHour FROM #DateTimeTable) dtt
WHERE td.login_time <= dtt.RefHour
AND td.logout_time > dtt.RefHour
GROUP BY dtt.RefHour
给出这个结果;
RefHour Users
2016-06-08 09:00:00.000 1
2016-06-08 10:00:00.000 9
该表的优点是,一旦创建,您就可以在数据库中的所有查询数中使用结果,以提高性能。