计算特定 window 内发生的两次之间的持续时间
Calculating duration between two times that occur within a specific window
我正在尝试计算 START_TIME 和 END_TIME 之间的持续时间,它们在 SQL Server 2016 的集合 windows 时间内发生。
我有一组数据如下所示:
| USER| START_TIME | END_TIME | DURATION | WINDOW_1_START | WINDOW_1_END | WINDOW_2_START | WINDOW_2_END |
|-----|------------------|------------------|----------|----------------|--------------|-----------------|--------------|
| jim | 2021-01-24 14:00 | 2021-01-24 16:00 | 120 | 17:00 | 20:00 | 20:00 | 22:00 |
| jim | 2021-01-24 16:00 | 2021-01-24 18:00 | 120 | 17:00 | 20:00 | 20:00 | 22:00 |
| jim | 2021-01-24 18:00 | 2021-01-24 19:30 | 90 | 17:00 | 20:00 | 20:00 | 22:00 |
| jim | 2021-01-24 19:30 | 2021-01-24 22:00 | 150 | 17:00 | 20:00 | 20:00 | 22:00 |
以上输出可以通过以下查询实现:
SELECT USER,
START_TIME,
END_TIME,
DATEDIFF ( minute, START_TIME, END_TIME ) AS DURATION
CAST ( '17:00' AS TIME ) AS WINDOW_1_START,
CAST ( '20:00' AS TIME ) AS WINDOW_1_END,
CAST ( '20:00' AS TIME ) AS WINDOW_2_START,
CAST ( '22:00' AS TIME ) AS WINDOW_2_END
FROM EVENTS
;
我想计算 WINDOW_1 和 WINDOW_2 内出现的每一行的持续时间。我想要的输出将添加 WINDOW_1_DURATION 和 WINDOW_2_DURATION 列。例如,第二行的 WINDOW_1_DURATION 为 60。
理想情况下,我希望在不使用函数或创建新表的情况下实现这一目标。
编辑:
所需的输出如下所示:
| USER| START_TIME | END_TIME | DURATION | WINDOW_1_START | WINDOW_1_END | WINDOW_2_START | WINDOW_2_END | WINDOW_1_DURATION | WINDOW_2_DURATION |
|-----|------------------|------------------|----------|----------------|--------------|-----------------|--------------|---------------------------------------|
| jim | 2021-01-24 14:00 | 2021-01-24 16:00 | 120 | 17:00 | 20:00 | 20:00 | 22:00 | 0 | 0 |
| jim | 2021-01-24 16:00 | 2021-01-24 18:00 | 120 | 17:00 | 20:00 | 20:00 | 22:00 | 60 | 0 |
| jim | 2021-01-24 18:00 | 2021-01-24 19:30 | 90 | 17:00 | 20:00 | 20:00 | 22:00 | 90 | 0 |
| jim | 2021-01-24 19:30 | 2021-01-24 22:00 | 150 | 17:00 | 20:00 | 20:00 | 22:00 | 30 | 120 |
编辑 2:作为对第 2 行的 WINDOW_1_DURATION 为 60 的示例的解释,这是 16:00 的 START_TIME 和18:00 的 END_TIME 与 17:00 的 WINDOW_1_START 和 20:00 的 WINDOW_1_END 一起出现。
以下查询将提供您想要的输出:
(逻辑:首先,我将 CAST start_time 和 end_time 作为开始时间和结束时间列中的时间。然后使用 Case 我试图确定重叠是如何发生的。例如,如果 WINDOW_1_START 小于开始时间并且 WINDOW_1_END 在开始时间和结束时间之间,那么重叠时间在开始时间和 Window_1_End 之间等)
with cte as (
SELECT [USER],
START_TIME,
END_TIME,
DATEDIFF ( minute, START_TIME, END_TIME ) AS DURATION,
CAST ( '17:00' AS TIME ) AS WINDOW_1_START,
CAST ( '20:00' AS TIME ) AS WINDOW_1_END,
CAST ( '20:00' AS TIME ) AS WINDOW_2_START,
CAST ( '22:00' AS TIME ) AS WINDOW_2_END,
cast(start_time as time)starttime,
cast(end_time as time)endtime
FROM EVENTS)
select * ,
case when (WINDOW_1_START between starttime and endtime and WINDOW_1_end between starttime and endtime ) then (datediff(minute,WINDOW_1_START,WINDOW_1_end))
when (WINDOW_1_START between starttime and endtime and WINDOW_1_END > endtime) then (datediff(minute,WINDOW_1_START,endtime))
when (WINDOW_1_START<starttime and WINDOW_1_END between starttime and endtime) then (datediff(minute,starttime,WINDOW_1_END))
when (WINDOW_1_START<starttime and WINDOW_1_END >endtime) then (datediff(minute,starttime,endtime)) end WINDOW_1_DURATION,
case when (WINDOW_2_START between starttime and endtime and WINDOW_2_end between starttime and endtime ) then (datediff(minute,WINDOW_2_START,WINDOW_2_end))
when (WINDOW_2_START between starttime and endtime and WINDOW_2_END > endtime) then (datediff(minute,WINDOW_2_START,endtime))
when (WINDOW_2_START<starttime and WINDOW_2_END between starttime and endtime) then (datediff(minute,starttime,WINDOW_2_END))
when (WINDOW_2_START<starttime and WINDOW_2_END >endtime) then (datediff(minute,starttime,endtime)) end WINDOW_2_DURATION
from cte
输出:
我正在尝试计算 START_TIME 和 END_TIME 之间的持续时间,它们在 SQL Server 2016 的集合 windows 时间内发生。
我有一组数据如下所示:
| USER| START_TIME | END_TIME | DURATION | WINDOW_1_START | WINDOW_1_END | WINDOW_2_START | WINDOW_2_END |
|-----|------------------|------------------|----------|----------------|--------------|-----------------|--------------|
| jim | 2021-01-24 14:00 | 2021-01-24 16:00 | 120 | 17:00 | 20:00 | 20:00 | 22:00 |
| jim | 2021-01-24 16:00 | 2021-01-24 18:00 | 120 | 17:00 | 20:00 | 20:00 | 22:00 |
| jim | 2021-01-24 18:00 | 2021-01-24 19:30 | 90 | 17:00 | 20:00 | 20:00 | 22:00 |
| jim | 2021-01-24 19:30 | 2021-01-24 22:00 | 150 | 17:00 | 20:00 | 20:00 | 22:00 |
以上输出可以通过以下查询实现:
SELECT USER,
START_TIME,
END_TIME,
DATEDIFF ( minute, START_TIME, END_TIME ) AS DURATION
CAST ( '17:00' AS TIME ) AS WINDOW_1_START,
CAST ( '20:00' AS TIME ) AS WINDOW_1_END,
CAST ( '20:00' AS TIME ) AS WINDOW_2_START,
CAST ( '22:00' AS TIME ) AS WINDOW_2_END
FROM EVENTS
;
我想计算 WINDOW_1 和 WINDOW_2 内出现的每一行的持续时间。我想要的输出将添加 WINDOW_1_DURATION 和 WINDOW_2_DURATION 列。例如,第二行的 WINDOW_1_DURATION 为 60。
理想情况下,我希望在不使用函数或创建新表的情况下实现这一目标。
编辑:
所需的输出如下所示:
| USER| START_TIME | END_TIME | DURATION | WINDOW_1_START | WINDOW_1_END | WINDOW_2_START | WINDOW_2_END | WINDOW_1_DURATION | WINDOW_2_DURATION |
|-----|------------------|------------------|----------|----------------|--------------|-----------------|--------------|---------------------------------------|
| jim | 2021-01-24 14:00 | 2021-01-24 16:00 | 120 | 17:00 | 20:00 | 20:00 | 22:00 | 0 | 0 |
| jim | 2021-01-24 16:00 | 2021-01-24 18:00 | 120 | 17:00 | 20:00 | 20:00 | 22:00 | 60 | 0 |
| jim | 2021-01-24 18:00 | 2021-01-24 19:30 | 90 | 17:00 | 20:00 | 20:00 | 22:00 | 90 | 0 |
| jim | 2021-01-24 19:30 | 2021-01-24 22:00 | 150 | 17:00 | 20:00 | 20:00 | 22:00 | 30 | 120 |
编辑 2:作为对第 2 行的 WINDOW_1_DURATION 为 60 的示例的解释,这是 16:00 的 START_TIME 和18:00 的 END_TIME 与 17:00 的 WINDOW_1_START 和 20:00 的 WINDOW_1_END 一起出现。
以下查询将提供您想要的输出: (逻辑:首先,我将 CAST start_time 和 end_time 作为开始时间和结束时间列中的时间。然后使用 Case 我试图确定重叠是如何发生的。例如,如果 WINDOW_1_START 小于开始时间并且 WINDOW_1_END 在开始时间和结束时间之间,那么重叠时间在开始时间和 Window_1_End 之间等)
with cte as (
SELECT [USER],
START_TIME,
END_TIME,
DATEDIFF ( minute, START_TIME, END_TIME ) AS DURATION,
CAST ( '17:00' AS TIME ) AS WINDOW_1_START,
CAST ( '20:00' AS TIME ) AS WINDOW_1_END,
CAST ( '20:00' AS TIME ) AS WINDOW_2_START,
CAST ( '22:00' AS TIME ) AS WINDOW_2_END,
cast(start_time as time)starttime,
cast(end_time as time)endtime
FROM EVENTS)
select * ,
case when (WINDOW_1_START between starttime and endtime and WINDOW_1_end between starttime and endtime ) then (datediff(minute,WINDOW_1_START,WINDOW_1_end))
when (WINDOW_1_START between starttime and endtime and WINDOW_1_END > endtime) then (datediff(minute,WINDOW_1_START,endtime))
when (WINDOW_1_START<starttime and WINDOW_1_END between starttime and endtime) then (datediff(minute,starttime,WINDOW_1_END))
when (WINDOW_1_START<starttime and WINDOW_1_END >endtime) then (datediff(minute,starttime,endtime)) end WINDOW_1_DURATION,
case when (WINDOW_2_START between starttime and endtime and WINDOW_2_end between starttime and endtime ) then (datediff(minute,WINDOW_2_START,WINDOW_2_end))
when (WINDOW_2_START between starttime and endtime and WINDOW_2_END > endtime) then (datediff(minute,WINDOW_2_START,endtime))
when (WINDOW_2_START<starttime and WINDOW_2_END between starttime and endtime) then (datediff(minute,starttime,WINDOW_2_END))
when (WINDOW_2_START<starttime and WINDOW_2_END >endtime) then (datediff(minute,starttime,endtime)) end WINDOW_2_DURATION
from cte
输出: