SQL查看附近数据间隔的函数
SQL Function to Look at near-by Intervals of data
我正在尝试确定是否有某种 SQL 函数可以让我查看附近的数据间隔以将它们聚合到其他聚合函数中。
我当前的数据如下所示,每 5 分钟出现一次,每个实体在给定时间段内每天有一个条目。
- 实体A 20200201 00:10:00 21.0
- 实体A 20200201 00:15:00 23.0
- 实体A 20200201 00:20:00 23.0
- ...
- 实体A 20200202 00:15:00 22.1
- ...
- 实体A 20200203 00:15:00 13.3
我已经有几个聚合函数在查看时间范围内的整个数据系列,我给它提供一个参数来告诉它我想查看一天中的什么时间,就像“00:15”一样简单一个参数(声明为日期时间),通过连接 Facts.Timekey = 4 即“00:15”作为一天中的第 4 个 5 分钟间隔。
--仅假设单个实体的简化和简单函数。
DECLARE @TimeFrame DateTime = '00:15:00'
(SELECT stdevp(convert(decimal(19,6), facts.ActualValue))
FROM FactsDTValue as Facts
LEFT JOIN DimTime DT on Facts.TimeKey = DT.TimeKey
Where DT.TimeName24 = @TimeFrame
Group by Fact.Entity);
我想为上面的函数做的是简单的函数,可以在更大范围内应用 00:15 左右的时间范围。
如此有效,如果参数传递 00:15 并说我有另一个参数设置为 3,它将为系列中的每一天获得 facts.ActualValue 的值.. 不仅仅是单一的执行聚合函数的值,如 STDDEVP、AVERAGE、MAX、MIN、Median、Mode 等。
- 00:00 (-3)
- 00:05 (-2)
- 00:10 (-1)
- 00:15 (0)
- 00:20 (+1)
- 00:25 (+2)
- 00:30 (+3)
如此有效地每天采样 7 值(当参数设置为 3 时)与仅 1.
如果我需要这样做来处理边缘值和 NULL,就好像没有收到实体的数据一样,周期根本不存在。
我正在使用 MS SQL Server 2016;解决这个问题的最佳方法是什么?是否有一个功能可以自动执行此操作,或者我可能只是遗漏了一些非常简单的东西?
您可以使用 window 函数来做到这一点。逻辑是用row_number()
枚举每个实体和每一天的行,然后标识每个分区中时间与参数匹配的行的行号。然后您可以使用该信息进行过滤。
假设您的 table 的列是 entity
(实体)、ts
(日期时间列)和 val
(值),那将是:
select entity, cast(ts as day) ts_day, stdevp(val) val_stdevp
from (
select
t.*,
max(case when cast(ts as time) = @TimeFrame then rn end)
over(partition by entity, cast(ts as date)) rn0
from (
select
t.*,
row_number() over(partition by entity, cast(ts as date) order by ts) rn
from mytbale t
) t
) t
where rn between rn0 - 3 and rn0 + 3
group by entity, cast(ts as day)
这会为您每天为每个实体提供一条记录,其中包含 7 条目标记录的 stdevp()
值。
我正在尝试确定是否有某种 SQL 函数可以让我查看附近的数据间隔以将它们聚合到其他聚合函数中。
我当前的数据如下所示,每 5 分钟出现一次,每个实体在给定时间段内每天有一个条目。
- 实体A 20200201 00:10:00 21.0
- 实体A 20200201 00:15:00 23.0
- 实体A 20200201 00:20:00 23.0
- ...
- 实体A 20200202 00:15:00 22.1
- ...
- 实体A 20200203 00:15:00 13.3
我已经有几个聚合函数在查看时间范围内的整个数据系列,我给它提供一个参数来告诉它我想查看一天中的什么时间,就像“00:15”一样简单一个参数(声明为日期时间),通过连接 Facts.Timekey = 4 即“00:15”作为一天中的第 4 个 5 分钟间隔。
--仅假设单个实体的简化和简单函数。
DECLARE @TimeFrame DateTime = '00:15:00'
(SELECT stdevp(convert(decimal(19,6), facts.ActualValue))
FROM FactsDTValue as Facts
LEFT JOIN DimTime DT on Facts.TimeKey = DT.TimeKey
Where DT.TimeName24 = @TimeFrame
Group by Fact.Entity);
我想为上面的函数做的是简单的函数,可以在更大范围内应用 00:15 左右的时间范围。
如此有效,如果参数传递 00:15 并说我有另一个参数设置为 3,它将为系列中的每一天获得 facts.ActualValue 的值.. 不仅仅是单一的执行聚合函数的值,如 STDDEVP、AVERAGE、MAX、MIN、Median、Mode 等。
- 00:00 (-3)
- 00:05 (-2)
- 00:10 (-1)
- 00:15 (0)
- 00:20 (+1)
- 00:25 (+2)
- 00:30 (+3)
如此有效地每天采样 7 值(当参数设置为 3 时)与仅 1.
如果我需要这样做来处理边缘值和 NULL,就好像没有收到实体的数据一样,周期根本不存在。
我正在使用 MS SQL Server 2016;解决这个问题的最佳方法是什么?是否有一个功能可以自动执行此操作,或者我可能只是遗漏了一些非常简单的东西?
您可以使用 window 函数来做到这一点。逻辑是用row_number()
枚举每个实体和每一天的行,然后标识每个分区中时间与参数匹配的行的行号。然后您可以使用该信息进行过滤。
假设您的 table 的列是 entity
(实体)、ts
(日期时间列)和 val
(值),那将是:
select entity, cast(ts as day) ts_day, stdevp(val) val_stdevp
from (
select
t.*,
max(case when cast(ts as time) = @TimeFrame then rn end)
over(partition by entity, cast(ts as date)) rn0
from (
select
t.*,
row_number() over(partition by entity, cast(ts as date) order by ts) rn
from mytbale t
) t
) t
where rn between rn0 - 3 and rn0 + 3
group by entity, cast(ts as day)
这会为您每天为每个实体提供一条记录,其中包含 7 条目标记录的 stdevp()
值。