如何在SQL Server

时间:2016-06-08 08:23:31

标签: sql-server tsql

我想生成一个查询,输出一天中某些时间之间的并发用户数。我将使用变量来允许我选择特定的一天。

该表有一个login_time字段,它是datetime,还有一个logout_time字段,也是datetime。基本上,如果用户在该小时内的任何时间点登录,我希望能够输出到一小时列。

案例陈述不可扩展,所以如果我想减少到十五分钟而不是一小时,我实际上需要48个案例陈述。

有没有更好的方法来处理这样的查询以输出并发用户登录?很高兴能够在MSBI堆栈中的任何地方提供解决方案。

2 个答案:

答案 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

该表的优点是,一旦创建,您就可以在数据库中的所有查询数中使用结果,以提高性能。