SQL:从第一次出现到接下来的五分钟计算某个值的出现次数,并在下一次出现时重复相同的次数
SQL: Counting occurrence of certain value from its first appearance till next five minutes and repeat the same for the next occurence again
我需要找出一个值 34 从第一次出现到接下来的 5 分钟出现的次数。
然后在 5 分钟后再次执行相同的操作,再次获取值为 20 的记录,查看每个设备在接下来的 5 分钟内发生了多少次
假设我有以下 table:
DevID value DateTime
--------------------------------------------------
99 20 18-12-2016 18:10
99 34 18-12-2016 18:11
99 34 18-12-2016 18:12
99 20 18-12-2016 18:15
23 15 18-12-2016 18:16
28 34 18-12-2016 18:17
23 15 18-12-2016 18:18
23 12 18-12-2016 18:19
99 20 18-12-2016 18:20
99 34 18-12-2016 18:21
99 34 18-12-2016 18:22
99 34 18-12-2016 18:23
99 34 18-12-2016 18:24
99 34 18-12-2016 18:25
我对数字 34 很感兴趣。我想检查数字 34 的第一次出现,获取它的时间,然后计算这个数字 (34) 在接下来的 5 分钟内出现了多少次。基本上从第一次出现到出现 +5 分钟获取记录,并计算其中有多少有 34 个,如果超过 3 个,则列出该设备名称。
在下一个 5 分钟之前对下一个记录重复相同的 34。所以在上面的例子中,记录 99 将在 2016 年 12 月 18 日首次获得 34 18:11 但随后我们在接下来的 5 分钟内没有获得超过 3 个 34 的记录但是我们在 18-12 再次获得 34 -2016 18:21 并在接下来的 5 分钟内获得了 3 个以上的 34 个条目
因此上述 table 的预期输出将是设备 ID 99。
已编辑
我只想找到值 34。因此不需要在 5 分钟间隔内找到所有此类重复值的额外复杂性。
只是想知道在 5 分钟的时间间隔之间我们有 34 个重复了 3 次以上的设备(这应该是可以更改的,我也可以将其硬编码为 10 次)。
请调整您的 RDBMS,但它应该看起来像这样:
select b.*
from (
select value, min(DateTime) as md
from the_table
group by value
) as a
join the_table as b
on a.value = b.value
and b.DateTime between a.md and a.md + interval'5'minute
这可以按如下方式完成:
SELECT DevID
FROM t
WHERE Value = 34
AND 2 <= (
SELECT COUNT(*)
FROM t AS x
WHERE x.DevID = t.DevID
AND x.Value = t.Value
AND x.DateTime > t.DateTime
AND x.DateTime < DATEADD(MINUTE, 5, t.DateTime)
)
GROUP BY DevID
根据您计算 5 分钟的方式,您可能希望将 <
替换为 <=
。
最有效的方法是使用lag()
/lead()
:
select t.*
from (select t.*,
lead(datetime, 2) over (partition by devid order by datetime) as next2_dt
from t
where value = 34
) t
where next2_dt <= dateadd(minute, 5, datetime);
这会在第二个值之前达到峰值,并将该值的 datetime
与当前行的 datetime
进行比较。
我需要找出一个值 34 从第一次出现到接下来的 5 分钟出现的次数。
然后在 5 分钟后再次执行相同的操作,再次获取值为 20 的记录,查看每个设备在接下来的 5 分钟内发生了多少次
假设我有以下 table:
DevID value DateTime
--------------------------------------------------
99 20 18-12-2016 18:10
99 34 18-12-2016 18:11
99 34 18-12-2016 18:12
99 20 18-12-2016 18:15
23 15 18-12-2016 18:16
28 34 18-12-2016 18:17
23 15 18-12-2016 18:18
23 12 18-12-2016 18:19
99 20 18-12-2016 18:20
99 34 18-12-2016 18:21
99 34 18-12-2016 18:22
99 34 18-12-2016 18:23
99 34 18-12-2016 18:24
99 34 18-12-2016 18:25
我对数字 34 很感兴趣。我想检查数字 34 的第一次出现,获取它的时间,然后计算这个数字 (34) 在接下来的 5 分钟内出现了多少次。基本上从第一次出现到出现 +5 分钟获取记录,并计算其中有多少有 34 个,如果超过 3 个,则列出该设备名称。
在下一个 5 分钟之前对下一个记录重复相同的 34。所以在上面的例子中,记录 99 将在 2016 年 12 月 18 日首次获得 34 18:11 但随后我们在接下来的 5 分钟内没有获得超过 3 个 34 的记录但是我们在 18-12 再次获得 34 -2016 18:21 并在接下来的 5 分钟内获得了 3 个以上的 34 个条目
因此上述 table 的预期输出将是设备 ID 99。
已编辑
我只想找到值 34。因此不需要在 5 分钟间隔内找到所有此类重复值的额外复杂性。 只是想知道在 5 分钟的时间间隔之间我们有 34 个重复了 3 次以上的设备(这应该是可以更改的,我也可以将其硬编码为 10 次)。
请调整您的 RDBMS,但它应该看起来像这样:
select b.*
from (
select value, min(DateTime) as md
from the_table
group by value
) as a
join the_table as b
on a.value = b.value
and b.DateTime between a.md and a.md + interval'5'minute
这可以按如下方式完成:
SELECT DevID
FROM t
WHERE Value = 34
AND 2 <= (
SELECT COUNT(*)
FROM t AS x
WHERE x.DevID = t.DevID
AND x.Value = t.Value
AND x.DateTime > t.DateTime
AND x.DateTime < DATEADD(MINUTE, 5, t.DateTime)
)
GROUP BY DevID
根据您计算 5 分钟的方式,您可能希望将 <
替换为 <=
。
最有效的方法是使用lag()
/lead()
:
select t.*
from (select t.*,
lead(datetime, 2) over (partition by devid order by datetime) as next2_dt
from t
where value = 34
) t
where next2_dt <= dateadd(minute, 5, datetime);
这会在第二个值之前达到峰值,并将该值的 datetime
与当前行的 datetime
进行比较。