如何在SQL

时间:2016-01-12 18:28:46

标签: sql

这是我的问题 -

数据包含以userID和RequestTime格式向网站发出的用户请求。请求包含某个关键字是一个指定的搜索。在某一天,指定搜索后15分钟内的任何请求都被视为后续搜索,将被忽略。因此,如果用户在第一次搜索后15分钟内做了3次请求,然后在40分钟后用相同的关键字进行了第四次搜索,则第4次请求被认为是新搜索,第4次搜索后15分钟内的任何请求都被忽略,然后开始计算新的在这15分钟之后要求改变,等等。这是源数据集

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

过滤后,结果将如下所示

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

有关如何实现这一目标的任何建议?感谢

1 个答案:

答案 0 :(得分:0)

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

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中的行。时间&lt; T2.time&lt; T3.time

你可以拥有T1,T2,T3的4种组合,其中T1 < T2&lt; T3:

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)T3在T2后15分钟内不会发生 条款“AND T3.time&lt; T2.time + 15分钟“为false,因此不会按预期删除任何行

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

在组合B中,很明显条款“T1.time&gt; T2.time - 15分钟“是假的,但是因为我们要求大多数内部查询不存在,这意味着NOT EXISTS子句本身给出了一个真值而T3被删除了。

在组合D中,最内部的子句“T1.time&gt; T2.time - 15分钟“是真的,所以NOT EXISTS子句本身给出了一个假,T3不是(或者更好,在这种情况下,不是YET)删除。

可能是这样,如果T2将在第一轮被删除,那么在第二轮T3中将与新的T2(之前是T1或甚至比T1更早的事件)进行比较,T3无论如何都可以保持。但是,如果T1(不认为它是绝对的第一个)将在第1轮被删除,那么T2可能永远保留,T3将在第二轮被删除,接近T2,现在距离非足够远 - 删除前身。

在你的例子中 - 从T3的角度来看只考虑行,因为我们只删除了T3:

在第一轮中,11:45是T3没有前任,所以T2不存在,中间查询返回false。 在第一轮中,11:47是T3,其T2太近(T3.time&lt; T2.time + 15分钟),并且因为T1不存在,所以最内部的查询也是真的(来自NOT EXISTS-观点看法)。所以11:47将被删除。 在第一轮中,所有其他时间都将保留(现在)。

在第二轮比赛中,12:01是T3,以11:45作为T2,但距离足够远(T3.time&lt; T2.time + 15分钟为假),所以它会保持不变。 在第二轮中,12:11为T3,现在为12.10,为T2,距离T1太远,而且内部查询还可以,并且12:11必须删除。

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

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

因此,您需要反复运行此查询,直到不再删除任何行为止。 然后你得到了理想的结果。