MDX 查询计数 时间间隔内的登录次数
MDX query count Login occurences over time interval
我对如何建立我的事实和维度以产生以下结果感到困惑:
我想统计每个时间间隔内登录人数出现的次数。
在这种情况下,每 30 分钟一次。它看起来像这样
Example: Person1 login at 10:05:00 and logout at 12:10:00
Person2 login at 10:45:00 and logout at 11:25:00
Person3 login at 11:05:00 and logout at 14:01:00
TimeStart TimeEnd People logged
00:00:00 00:30:00 0
00:30:00 01:00:00 0
...
10:00:00 10:30:00 1
10:30:00 11:00:00 2
11:00:00 11:30:00 3
11:30:00 12:00:00 2
12:00:00 12:30:00 2
12:30:00 13:00:00 1
13:00:00 13:30:00 1
13:30:00 14:00:00 1
14:00:00 14:30:00 0
...
23:30:00 00:00:00 0
所以我有一个包含小时、半小时、刻钟的 DimTime 和 DimDate table
我有一个具有以下内容的 FactTimestamp table:
DateLoginID that points to DimDate dateID
DateLogoutID that points to DimDate dateID
TimeLoginID that points to DimTime timeID
TimeLogoutID that points to DimTime timeID
我想知道实现该目标需要什么样的立方体设计?
我已经在 sql 完成了,如果有帮助的话:
--Create tmp table for time interval
CREATE TABLE #tmp(
StartRange time(0),
EndRange time(0),
);
--Interval set to 30 minutes
DECLARE @Interval int = 30
-- Example with @Date = 2017-07-27: Set starttime at 2017-07-27 00:00:00
DECLARE @StartTime datetime = DATEADD(HOUR,0, @Date)
--Set endtime at 2017-07-27 23:59:59
DECLARE @EndTime datetime = DATEADD(SECOND,59,DATEADD(MINUTE,59,DATEADD(HOUR,23, @Date)))
--Populate tmp table with the time interval. from midnight to 23:59:59
;WITH cSequence AS
(
SELECT
@StartTime AS StartRange,
DATEADD(MINUTE, @Interval, @StartTime) AS EndRange
UNION ALL
SELECT
EndRange,
DATEADD(MINUTE, @Interval, EndRange)
FROM cSequence
WHERE DATEADD(MINUTE, @Interval, EndRange) <= @EndTime
)
INSERT INTO #tmp SELECT cast(StartRange as time(0)),cast(EndRange as time(0)) FROM cSequence OPTION (MAXRECURSION 0);
--Insert last record 23:30:00 to 23:59:59
INSERT INTO #tmp (StartRange, EndRange) values ('23:30:00','23:59:59');
SELECT tmp.StartRange as [Interval], COUNT(ts.TimeIn) as [Operators]
FROM #tmp tmp
JOIN Timestamp ts ON
--If timeIn is earlier than StartRange OR within the start/end range
(CAST(ts.TimeIn as time(0)) <= tmp.StartRange OR CAST(ts.TimeIn as time(0)) BETWEEN tmp.StartRange AND tmp.EndRange)
AND
--AND If timeOut is later than EndRange OR within the start/end range
CAST(ts.[TimeOut] as time(0)) >= tmp.EndRange OR CAST(ts.[TimeOut] as time(0)) BETWEEN tmp.StartRange AND tmp.EndRange
GROUP BY tmp.StartRange, tmp.EndRange
END
如果能提供任何有关如何在 mdx 中实现它的提示,我们将不胜感激。
老实说,我不会在 MDX 中针对 table 结构这样做。即使您成功获得 returns 该值的 MDX 查询,并且肯定可以完成,它很可能会非常复杂并且难以维护和调试,并且可能需要多次传递 table 获取数字,影响性能。
我认为这是定期快照的明确案例 table。选择你的粒度,但即使是 1 分钟的快照,你每天也会为所有其他维度的每个元组获得 1440 个数据点。如果您的 login/logout table 很大,您可能需要减小它以使其大小易于管理。最后,你得到一个 table 和 time_id
,count_of_logins
,以及你需要的其他维度的任何其他键,你需要的查询只是一个你想要的时间段的过滤器(给我一天中的所有时间,但仅过滤每小时的第 00 分钟和第 30 分钟)并且登录用户总数是微不足道的。
我对如何建立我的事实和维度以产生以下结果感到困惑:
我想统计每个时间间隔内登录人数出现的次数。
在这种情况下,每 30 分钟一次。它看起来像这样
Example: Person1 login at 10:05:00 and logout at 12:10:00
Person2 login at 10:45:00 and logout at 11:25:00
Person3 login at 11:05:00 and logout at 14:01:00
TimeStart TimeEnd People logged
00:00:00 00:30:00 0
00:30:00 01:00:00 0
...
10:00:00 10:30:00 1
10:30:00 11:00:00 2
11:00:00 11:30:00 3
11:30:00 12:00:00 2
12:00:00 12:30:00 2
12:30:00 13:00:00 1
13:00:00 13:30:00 1
13:30:00 14:00:00 1
14:00:00 14:30:00 0
...
23:30:00 00:00:00 0
所以我有一个包含小时、半小时、刻钟的 DimTime 和 DimDate table 我有一个具有以下内容的 FactTimestamp table:
DateLoginID that points to DimDate dateID
DateLogoutID that points to DimDate dateID
TimeLoginID that points to DimTime timeID
TimeLogoutID that points to DimTime timeID
我想知道实现该目标需要什么样的立方体设计?
我已经在 sql 完成了,如果有帮助的话:
--Create tmp table for time interval
CREATE TABLE #tmp(
StartRange time(0),
EndRange time(0),
);
--Interval set to 30 minutes
DECLARE @Interval int = 30
-- Example with @Date = 2017-07-27: Set starttime at 2017-07-27 00:00:00
DECLARE @StartTime datetime = DATEADD(HOUR,0, @Date)
--Set endtime at 2017-07-27 23:59:59
DECLARE @EndTime datetime = DATEADD(SECOND,59,DATEADD(MINUTE,59,DATEADD(HOUR,23, @Date)))
--Populate tmp table with the time interval. from midnight to 23:59:59
;WITH cSequence AS
(
SELECT
@StartTime AS StartRange,
DATEADD(MINUTE, @Interval, @StartTime) AS EndRange
UNION ALL
SELECT
EndRange,
DATEADD(MINUTE, @Interval, EndRange)
FROM cSequence
WHERE DATEADD(MINUTE, @Interval, EndRange) <= @EndTime
)
INSERT INTO #tmp SELECT cast(StartRange as time(0)),cast(EndRange as time(0)) FROM cSequence OPTION (MAXRECURSION 0);
--Insert last record 23:30:00 to 23:59:59
INSERT INTO #tmp (StartRange, EndRange) values ('23:30:00','23:59:59');
SELECT tmp.StartRange as [Interval], COUNT(ts.TimeIn) as [Operators]
FROM #tmp tmp
JOIN Timestamp ts ON
--If timeIn is earlier than StartRange OR within the start/end range
(CAST(ts.TimeIn as time(0)) <= tmp.StartRange OR CAST(ts.TimeIn as time(0)) BETWEEN tmp.StartRange AND tmp.EndRange)
AND
--AND If timeOut is later than EndRange OR within the start/end range
CAST(ts.[TimeOut] as time(0)) >= tmp.EndRange OR CAST(ts.[TimeOut] as time(0)) BETWEEN tmp.StartRange AND tmp.EndRange
GROUP BY tmp.StartRange, tmp.EndRange
END
如果能提供任何有关如何在 mdx 中实现它的提示,我们将不胜感激。
老实说,我不会在 MDX 中针对 table 结构这样做。即使您成功获得 returns 该值的 MDX 查询,并且肯定可以完成,它很可能会非常复杂并且难以维护和调试,并且可能需要多次传递 table 获取数字,影响性能。
我认为这是定期快照的明确案例 table。选择你的粒度,但即使是 1 分钟的快照,你每天也会为所有其他维度的每个元组获得 1440 个数据点。如果您的 login/logout table 很大,您可能需要减小它以使其大小易于管理。最后,你得到一个 table 和 time_id
,count_of_logins
,以及你需要的其他维度的任何其他键,你需要的查询只是一个你想要的时间段的过滤器(给我一天中的所有时间,但仅过滤每小时的第 00 分钟和第 30 分钟)并且登录用户总数是微不足道的。