SQL 问题:在任何给定时间内出现次数大于 N 的次数
SQL question: count of occurrence greater than N in any given hour
我正在查看登录日志(在 Netezza 中)并试图找到在任何 1 小时时间段(任何连续的 60 分钟时间段,而不是严格的时钟小时)内登录次数超过一定数量的用户) 自 12 月 1 日起。我查看了以下帖子,但大多数似乎都针对特定时间范围内的搜索,而不是任何给定时间段内的搜索。谢谢。
https://dba.stackexchange.com/questions/137660/counting-number-of-occurences-in-a-time-period
https://dba.stackexchange.com/questions/67881/calculating-the-maximum-seen-so-far-for-each-point-in-time
我想你可能会做类似的事情(为了简单起见,我将使用登录 table,将用户、日期时间作为单列):
with connections as (
select ua.user
, ua.datetime
from user_logons ua
where ua.datetime >= timestamp'2018-12-01 00:00:00'
)
select ua.user
, ua.datetime
, (select count(*)
from connections ut
where ut.user = ua.user
and ut.datetime between ua.datetime and (ua.datetime + 1 hour)
) as consecutive_logons
from connections ua
- 由您来完成您的列(用户、日期时间)
- dateadd 设施由您自行寻找(ua.datetime + 1 小时行不通);这或多或少取决于数据库的实现,例如 DATE_ADD in mySQL (https://www.w3schools.com/SQl/func_mysql_date_add.asp)
- 由于子查询(
select count(*) ...
),整个查询不会是最快的,因为它是一个相关的子查询——需要为每一行重新计算。
-
with
只是计算 user_logons
的子集以最小化其成本。这可能没有用,但是这会降低查询的复杂性。
使用存储函数或语言驱动(例如:java、php、...)函数可能会有更好的性能。
您可以使用分析函数 lag
回顾排序的时间戳序列,以查看早于 19 个条目的记录是否在一个小时的差异内:
with cte as (
select user_id,
login_time,
lag(login_time, 19) over (partition by user_id order by login_time) as lag_time
from userlog
order by user_id,
login_time
)
select user_id,
min(login_time) as login_time
from cte
where extract(epoch from (login_time - lag_time)) < 3600
group by user_id
输出将显示在一个小时内第20次登录时第一次出现的匹配用户。
我正在查看登录日志(在 Netezza 中)并试图找到在任何 1 小时时间段(任何连续的 60 分钟时间段,而不是严格的时钟小时)内登录次数超过一定数量的用户) 自 12 月 1 日起。我查看了以下帖子,但大多数似乎都针对特定时间范围内的搜索,而不是任何给定时间段内的搜索。谢谢。
https://dba.stackexchange.com/questions/137660/counting-number-of-occurences-in-a-time-period
https://dba.stackexchange.com/questions/67881/calculating-the-maximum-seen-so-far-for-each-point-in-time
我想你可能会做类似的事情(为了简单起见,我将使用登录 table,将用户、日期时间作为单列):
with connections as (
select ua.user
, ua.datetime
from user_logons ua
where ua.datetime >= timestamp'2018-12-01 00:00:00'
)
select ua.user
, ua.datetime
, (select count(*)
from connections ut
where ut.user = ua.user
and ut.datetime between ua.datetime and (ua.datetime + 1 hour)
) as consecutive_logons
from connections ua
- 由您来完成您的列(用户、日期时间)
- dateadd 设施由您自行寻找(ua.datetime + 1 小时行不通);这或多或少取决于数据库的实现,例如 DATE_ADD in mySQL (https://www.w3schools.com/SQl/func_mysql_date_add.asp)
- 由于子查询(
select count(*) ...
),整个查询不会是最快的,因为它是一个相关的子查询——需要为每一行重新计算。 -
with
只是计算user_logons
的子集以最小化其成本。这可能没有用,但是这会降低查询的复杂性。
使用存储函数或语言驱动(例如:java、php、...)函数可能会有更好的性能。
您可以使用分析函数 lag
回顾排序的时间戳序列,以查看早于 19 个条目的记录是否在一个小时的差异内:
with cte as (
select user_id,
login_time,
lag(login_time, 19) over (partition by user_id order by login_time) as lag_time
from userlog
order by user_id,
login_time
)
select user_id,
min(login_time) as login_time
from cte
where extract(epoch from (login_time - lag_time)) < 3600
group by user_id
输出将显示在一个小时内第20次登录时第一次出现的匹配用户。