首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何在SQL中以递归方式减少特定时间间隔后的行集

如何在SQL中以递归方式减少特定时间间隔后的行集
EN

Stack Overflow用户
提问于 2016-01-13 02:28:46
回答 1查看 48关注 0票数 0

我的问题是-

数据包含用户对网站的请求,格式为userID和RequestTime。包含特定关键字的请求是一个指定的搜索。在指定日期内,指定搜索后15分钟内的任何请求都将被视为后续搜索,并将被忽略。因此,如果用户在第一次搜索后15分钟内完成了3个请求,然后在40分钟后使用相同关键字进行了第四次搜索,则第四次请求被视为新搜索,第四次搜索后15分钟内的任何请求都将被忽略,然后在这15分钟后开始计算新请求,依此类推。以下是源数据集

代码语言:javascript
运行
复制
ClientID    RequestTime
a1  1/10/2016 11:45
a1  1/10/2016 11:47
a1  1/10/2016 12:01
a1  1/10/2016 12:11
a1  1/10/2016 12:16
a2  1/10/2016 11:47
a2  1/10/2016 12:16
a3  1/10/2016 12:16

过滤后,结果将如下所示

代码语言:javascript
运行
复制
ClientID    RequestTime
a1  1/10/2016 11:45
a1  1/10/2016 12:01
a1  1/10/2016 12:16
a2  1/10/2016 11:47
a2  1/10/2016 12:16
a3  1/10/2016 12:16

对如何实现这一点有什么建议吗?谢谢

EN

回答 1

Stack Overflow用户

发布于 2016-01-13 02:44:28

您应该多次运行下一个查询,直到不再删除任何行:

代码语言:javascript
运行
复制
DELETE FROM T3
WHERE EXISTS
   (SELECT 1 FROM T2
      WHERE T3.time > T2.time
            AND T3.time < T2.time + 15 minutes
            AND NOT EXISTS
              (SELECT  1 FROM T1
                WHERE T1.time < T2.time
                      AND T1.time > T2.time - 15 minutes))

解释

T1、T2和T3是时间T1中的行。时间

您可以使用任意T1、T2、T3的4种组合,其中T1 < T2 < T3:

代码语言:javascript
运行
复制
All more than 15 minutes apart (combi A):

T1
T2 - 15 minutes
T2
T2 + 15 minutes
T3

or T3 < T2 + 15 (combi B):

T1
T2 - 15 minutes
T2
T3
T2 + 15 minutes

or T1 > T2 - 15 minutes (combi C):

T2 - 15 minutes
T1
T2
T2 + 15 minutes
T3

or both T3 < T2 + 15 and T1 > T2 - 15 minutes (combi D)

T2 - 15 minutes
T1
T2
T3
T2 + 15 minutes

在组合A(和C)中,在T2之后的15分钟内,“T2 T3.time < T2.time + 15分钟”子句为假,因此不会像预期的那样删除任何行

在组合B(和D)中,T3距离T2不到15分钟,但它不确定T2是否会自己保留。

在组合B中,很明显“T1.time> T2.time - 15分钟”子句是假的,但是当我们要求大多数内部查询不应该存在时,这意味着NOT exists子句本身给出true,并且T3被删除。

在组合D中,最内部的子句“T1.time> T2.time - 15分钟”是真的,所以NOT EXISTS子句本身给出了假,并且T3没有被删除(或者更好,在这种情况下,还没有被删除)。

这可能是这样的,如果T2将在第一轮中被删除,那么在第二轮中,T3将与新的T2 (之前是T1,甚至是比T1更早的事件)进行比较,该T3无论如何都可以保留。然而,如果T1 (不要认为它是绝对的第一个)将在第一轮中被删除,那么T2可能永远留在那里,并且T3将在第二轮中被删除,以便接近现在离未被删除的前辈足够远的T2。

在您的示例中-仅从T3的角度考虑行,因为我们只删除T3:

在第一轮中,11:45的T3没有前置查询,因此它的T2不存在,中间的查询返回false。在第一轮中,11:47的T3有一个太接近的T2 (T3.time < T2.time + 15分钟),并且由于T1不存在,所以最内部的查询也是真的(从不存在的角度来看)。所以11点47分将被删除。在第一轮中,所有其他时间都将留下来(目前)。

在第二轮中,12:01为T3的时间有11:45为T2,但距离足够远(T3.time < T2.time + 15分钟为假),因此它将留下来。在第二轮中,12:11的T3现在作为T2有12.10,这太接近了,因为T2离T1足够远,内部查询也是ok的,12:11必须删除。

在第三轮中,12:16不会被删除,因为12:11为它腾出了空间。

这很复杂,但我希望我的解释能有所帮助。

因此,您需要一遍又一遍地运行此查询,直到不再删除任何行。然后你就可以得到想要的结果了。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34751213

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档