Sql 如何检查两个日期时间变量(from和to)是否属于特定范围?
我有一个表,它在机器中存储用户会话的日志。它有3列,我将使用。time\u from、time\u to和用户名。我想做的是计算那台电脑的高峰使用时间。为此,我将得到每小时使用的总分钟数和用户数。我试图得到会话的持续时间,这些持续时间在特定的时间范围内,如 时间从>0:00到<1:00,但仅适用于少于一小时的会话。 在我的表格中,有长达6小时的课程,这些课程将在夜间进行。 我的基本要求是获得特定日期内每24小时的会话持续时间,但我无法处理长度超过1小时的会话。有没有什么方法可以完全通过使用SQL来实现这一点,或者我必须用另一个程序来处理它Sql 如何检查两个日期时间变量(from和to)是否属于特定范围?,sql,sql-server,Sql,Sql Server,我有一个表,它在机器中存储用户会话的日志。它有3列,我将使用。time\u from、time\u to和用户名。我想做的是计算那台电脑的高峰使用时间。为此,我将得到每小时使用的总分钟数和用户数。我试图得到会话的持续时间,这些持续时间在特定的时间范围内,如 时间从>0:00到
顺便说一句,我正在使用ms sql server。制作一个间隔表,然后:
SELECT interval
, count(*) as sessions
, count(distinct username) as users
, SUM(DATEDIFF(s, time_to, time_from)) as seconds_used
FROM (
SELECT user_sessions.username
, intervals.interval
, CASE
WHEN intervals.time_from < user_sessions.time_from
THEN user_sessions.time_from
ELSE intervals.time_from
END as time_from
, CASE
CASE
WHEN user_sessions.time_to < intervals.time_to
THEN user_sessions.time_to
ELSE intervals.time_to
END as time_from
FROM user_sessions
JOIN intervals
ON intervals.time_from < user_sessions.time_to
AND user_sessions.time_from < intervals.time_to
)
GROUP BY interval;
请注意,我不使用MS SQL server,因此我将此SQL设置为通用的,并且相当可移植。也许有一种更简洁的方法可以做到这一点。我也没有进行测试,因此可能会有明显的、希望很容易修复的错误。基本上,我的解决方案需要建立一个日历,列出开始日期时间和结束日期时间之间的所有小时,然后计算每个小时间隔内的分钟数,最后完全按时间间隔计算
Declare @StartDate datetime
Declare @EndDate datetime
Set @StartDate = ...
Set @EndDate = ...
;With Calendar As
(
Select 1 As Num, DateAdd(d, DateDiff(d, 0, @StartDate), 0) As [Date]
Union All
Select Num + 1, DateAdd(hh, 1, [Date])
From Calendar
Where [Date] <= @EndDate
)
, Ranges As
(
Select C1.Num, C1.Date As StartDate, Coalesce(C2.Date, @EndDate) As EndDate
From Calendar As C1
Left Join Calendar As C2
On C2.[Num] = C1.Num + 1
)
, UsageByHour As
(
Select U.username, R.Num As RangeNum, DateDiff( mi, R.StartDate, U.time_to ) As UsageMinutes
From user_sessions As U
Join Ranges As R
On U.time_from Between R.StartDate And R.EndDate
And U.time_to <= R.EndDate
Union All
Select U.username, R.Num, DateDiff( mi, U.time_from, R.EndDate )
From user_sessions As U
Join Ranges As R
On U.time_from Between R.StartDate And R.EndDate
And U.time_to > R.EndDate
Union All
Select U.username, R.Num, DateDiff( mi, R.StartDate, U.time_to )
From user_sessions As U
Join Ranges As R
On U.time_to Between R.StartDate And R.EndDate
And U.time_from < R.StartDate
)
Select U.username, C.StartDate, C.EndDate, Sum( U.UsageMinutes )
From Usage As U
Join Calendar As C
On C.Num = U.RangeNum
Group By U.username, C.StartDate, C.EndDate
Option ( MaxRecursion 0 );
...
, UsageByInterval As
(
Select U.username, C.StartDate, C.EndDate, Sum( U.UsageMinutes ) As UsageMinutes
From Usage As U
Join Calendar As C
On C.Num = U.RangeNum
Group By U.username, C.StartDate, C.EndDate
)
, UsageRanking As
(
Select U.username, C.StartDate, C.EndDate, UsageMinutes
, Row_Number() Over( Partition By U.username
Order By UsageMinutes Desc ) As Rnk
From UsageByInterval
)
Select username, StartDate, EndDate, UsageMinutes
From UsageRanking
Where Rnk = 1