【问题标题】:select query to get data which occurs five times or more within 24 hours选择查询获取24小时内出现5次或以上的数据
【发布时间】:2018-09-16 18:18:33
【问题描述】:

对不起,我尝试研究它,但似乎找不到合适的东西。

以下我已经找到了,但不能用于我的问题:

Filtering MySQL query result set to yield multiple occurences within a specific period of time

SQL Query To Obtain Value that Occurs more than once

我无法修改这些语句来解决我的问题。

我想选择一个数据在 24 小时内在一个表中出现五次或更多次的所有数据。 该表包含过去几年的数据。

表格未按日期排序(时间戳 dd.mm.yy hh:mm:ss,ssssssss)

这向我显示了总体发生率 >= 5,但如果这发生在 24 小时内,则不会。

SELECT Column, COUNT(*) FROM Table
GROUP BY Column
HAVING COUNT(*) >= 5;

欢迎对搜索关键字提出任何建议。

在此先感谢您。 最良好的问候 丹约

编辑: 谢谢大家的帮助,我很抱歉提出了不好的问题。 我会尽力回答你所有的问题。

@mathguy 数据库版本为 12c。

它确实有一列用于“数据”,另一列用于日期(时间戳)。我想在该值第一次出现后的

@马修·麦克皮克 我仍在尝试理解您的 SQL 语句。对不起,我对 SQL 是全新的。从我问我的问题的方式来看,这很明显:(。

@Aurelian 我的问题问得不好。所以你的答案不合适,对不起。

@all 我对我提出的错误问题和浪费您的时间感到难过。

希望你能接受我的道歉。

最好的问候 丹约

EDIT2:我现在正在尝试这个

begin
for i in (select Table.DATE(Timestamp), Table.IP, Table.Value from Table) 
loop
  dbms_output.put_line(i.Value); (instead of this output, i would like to add another loop and compare the Date(Timestamp) with i.DATE and count if matches
end loop;
end;

【问题讨论】:

  • 你的桌子是什么样子的?它是否有一列用于“数据”,另一列用于日期/时间(在 Oracle 中,数据类型为 datetimestamp)?并且您需要在 24 小时窗口内的“数据”列中查找相同值的出现?如果是这样,这里还有几个问题。 “24 小时内”是指
  • 还有:您使用的是什么版本的 Oracle? SELECT * FROM V$VERSION 会告诉你,如果你不知道。
  • 你好 mathguy,谢谢你的帮助。我已经更新了我的问题。
  • 您只想要第一次出现后 24 小时内的出现次数吗?因此,如果您在周二出现 1 次“数据”值,然后在周五出现 20 次,您希望看到“数据”值出现“1”,而不是 20?
  • 嗨,我想在他第一次出现后 24 小时内出现超过 5 次时查看该值。示例:它现在发生一次。接下来的 4 次发生在 3 天内(从现在起),然后是 1 次发生在 10 天内(从现在起)。我的 sql 语句的结果不会显示任何内容。

标签: sql oracle


【解决方案1】:

您可以使用以下代码:

SELECT DISTINCT Column, COUNT(*) 
FROM TABLE
WHERE date >= SYSDATE - 1
GROUP BY Column
HAVING COUNT(*) >= 5;   

【讨论】:

  • 哦...我们对“24 小时内”的解释不同。也许你是对的(在“过去 24 小时内”)。我理解它的意思是“在第一次和最后一次之间的 24 小时内”(可能是八个月前)。
  • 我假设他们需要上述查询的“24 小时内”。我希望它可以工作并满足要求。
  • “24 小时内”并不意味着 过去 24 小时内(从“现在”开始计算) - 如果您必须在开始后一小时内完成某件事,它必须“在一小时内完成”。但对于非英语为母语的人,它可能意味着您的假设。
  • 我同意,一旦问题更新,我会相应地修改我的答案。
【解决方案2】:

您可以使用此表达式计算过去 24 小时内每个值的出现次数:

 COUNT(*) OVER (PARTITION BY column
                ORDER BY date_column 
                RANGE NUMTODSINTERVAL(24,'HOUR') PRECEDING

然后,获取该表达式至少为 5 的行。

我没有您的数据,但这里有一个使用 DBA_OBJECTS 的示例。此版本将显示对象OWNER 在前五天更新了 5 个或更多对象的任何对象更新。

with five_day_count as 
( select o.owner, 
  last_ddl_time,
  count(*) over ( partition by owner 
                  order by last_ddl_time 
                  range numtodsinterval(5, 'DAY') PRECEDING ) cnt
  from dba_objects o)
SELECT owner, last_ddl_time, cnt 
FROM five_day_count
WHERE cnt >= 5

...而且,只是为了好玩,此查询将为每个OWNER 提供一行 - 为该用户提供最新对象的五天间隔。此版本的变体可能更适合您的需要。

with five_day_count as 
( select o.owner, 
         last_ddl_time range_end,
         min(last_ddl_time) 
            over ( partition by owner 
                   order by last_ddl_time 
                   range numtodsinterval(5, 'DAY') PRECEDING ) range_start,
         count(*) 
            over ( partition by owner 
                   order by last_ddl_time range 
                   numtodsinterval(5, 'DAY') PRECEDING ) cnt
  from dba_objects o),
max_counts as 
( SELECT owner, 
         range_start, 
         range_end, 
         cnt, 
         row_number() 
             over ( partition by owner 
                    order by cnt desc, 
                             range_end desc) rn 
  FROM five_day_count
  WHERE cnt > = 5)
select owner, range_start, range_end, cnt
from max_counts
where rn = 1;

【讨论】:

  • 您好 Matthew McPeak,感谢您的帮助。我已经更新了我的问题。
【解决方案3】:

我想在该值第一次出现后的

每个值的第一次出现:

select value, min(timestmp) from mytable group by value;

现在我们必须检查一个值在第一次出现后是否至少再出现四次:

select value, min(timestmp)
from mytable m
group by value
having
(
  select count(*)
  from mytable following24hours
  where following24hours.value = m.value
    and following24hours.timestmp > min(m.timestmp) 
    and following24hours.timestmp < min(m.timestmp) + interval '24' hour
) >= 4;

【讨论】:

  • 这是我正在寻找的语句。谢谢你和所有帮助过的人。我很高兴不需要循环。
  • 循环正是这个解决方案所做的,你只是看不到它——它隐藏在 SQL 代码后面。我发布了一个使用 MATCH_RECOGNIZE 子句(在 Oracle 12.1 及更高版本中可用)的解决方案,它应该比这个解决方案更有效;但只有您可以决定,根据您的实际数据运行解决方案。
  • 我也尝试过 mathguy 的 MATCH_RECOGNIZE 解决方案。它也解决了我的问题。谢谢你的解决方案。
【解决方案4】:

在 Oracle 12 中,您可以使用 MATCH_RECOGNIZE 子句来获得非常干净和高效的解决方案。 (您可以根据接受的答案对其进行测试,以验证它是否正确并查看哪个对您的实际数据更有效)。

select value, first_timestmp
from   mytable
match_recognize(
  partition by value
  order by     timestmp
  measures     a.timestmp as first_timestmp
  one row per match
  pattern      ( a b{4,} )
  define       b as b.timestmp <= a.timestmp + interval '24' hour
)
;

【讨论】:

  • 嘿,mathguy,这个解决方案也解决了我的问题。我的表只有 2k 行(仍在增长)。目前,我看不出速度(效率)有任何差异。现在我必须在谷歌和文档的帮助下了解这两种解决方案是如何工作的。非常感谢您的帮助。
猜你喜欢
  • 2011-08-28
  • 1970-01-01
  • 2017-05-27
  • 1970-01-01
  • 2014-11-02
  • 2020-10-07
  • 2021-07-25
  • 1970-01-01
  • 2015-12-18
相关资源
最近更新 更多