查询有或无日期约束的事件序列
Posted
技术标签:
【中文标题】查询有或无日期约束的事件序列【英文标题】:Querying on Event Sequences With or Without Date Constraints 【发布时间】:2017-09-01 13:50:05 【问题描述】:假设我有一个包含 0:many 时间事件的人的数据库。
PERSON TABLE:
ID Person
-- ------
1 Patrick
2 Sandy
EVENT TABLE:
ID Event
-- -----
1 blow bubbles
2 visit SpongeBob
3 eat at the Krusty Krab
PERSON EVENT TABLE:
Person_ID Event_ID Date
1 3 2017-05-05
1 3 2017-05-09
1 2 2017-05-10
2 1 2017-05-04
2 3 2017-05-15
我对如何进行这样的查询很感兴趣:
找出所有在 3 天内在 Krusty Krab 吃过饭的人 拜访海绵宝宝。
找到所有曾经吹过泡泡,然后访问过海绵宝宝的人,然后 以特定顺序再次吹泡泡(其他干预事件 没问题)。
找到所有曾经吹过泡泡,然后访问过海绵宝宝的人,然后 以特定顺序再次吹泡泡(其他干预事件 不行)。
找出所有曾经在 Krusty Krab 吃过至少 5 次的人 7天。
这种类型的查询有名称吗?是否有用于处理此类查询的通用 SQL 策略?我对如何快速进行此类查询特别感兴趣。是否有任何专门的数据库或索引可以帮助提高此类查询的性能?
【问题讨论】:
看起来像家庭作业或类似的。向我们展示您的尝试 - 添加预期结果以及您的不同查询尝试。同时标记您正在使用的 dbms。 你必须说“馄饨,馄饨,把奎里奥利给我。”另外,请提供您尝试过的方法。 同意前面的 cmets,如果他正在寻找如何编写这些查询。 不同意,如果他试图理解这些类型的查询——这就是我对这个问题的理解。 查询示例不需要 SQL 代码,只需回答我的问题。我处理医院数据,我们经常有兴趣寻找具有特定程序/诊断顺序的患者。我知道如何在代码中进行这些比较,但需要一种更省时的方法,老实说不知道从哪里开始。 【参考方案1】:有这么多不同的方法来做这样的事情......因为你的 cmets 只是在寻找逻辑方向......我希望这会有所帮助并且有意义。
找到所有在访问海绵宝宝后 3 天内曾在 Krusty Krab 吃过饭的人。
您可以通过选择对 Krusty Krab 的所有访问,然后查看该人是否为 IN
的查询来检查他们是否在 3 天前访问 Spongebob 来实现此目的。提示:... WHERE PersonId IN (SELECT PersonId WHERE DATEDIFF(day, SpongebobVisit, KrustyKrabVisit) >= 3)
找出所有曾经吹过泡泡,然后访问海绵宝宝,然后按特定顺序再次吹泡泡的人(其他中间事件都可以)。
您可以创建三个子查询表...吹泡泡、拜访海绵宝宝和吹泡泡。然后JOIN
在链中,其中每个JOIN
s 的日期都大于最后一个事件。由于INNER JOIN
,它只会返回这些事件按顺序排列的行。
找出所有曾经吹过泡泡,然后访问海绵宝宝,然后按特定顺序再次吹泡泡的人(其他中间事件不正常)。
按人员和日期对表格进行排序,并查看LEAD
AND LAG
函数。
找出所有曾在 7 天内至少在 Krusty Krab 吃过 5 次的人。
看这里:Sql Query to find A series of dates that occur within 5 minutes of each other?
是否有任何专门的数据库或索引可以帮助提高此类查询的性能?
对于这些类型的查询,ID 上的标准索引应该足够了。
编辑:我不是在宣传,但这里有一位用户写了一本名为“SQL 反模式”的书,该书真正深入探讨了解决此类有趣问题的正确方法。他通常会展示人们通常会做的一种方式,然后才是正确的方式。
【讨论】:
【参考方案2】:这些查询在功能上不够接近,无法拥有一个通用的基于函数的名称或策略。至少没有我能想到的。
它们的用法可能足够接近,可以将它们称为所有“数据挖掘”或“营销”查询。但是,如果这就是您问的原因,我怀疑其中任何一个在谷歌搜索通用策略时是否有用。
如果您有兴趣让不太懂 sql 的用户创建和运行这样的临时查询以及他们可能想出的任何其他查询,您可能会考虑为他们提供一个非规范化视图,甚至是一个包含他们每个维度的多维数据集可以想到想用。
【讨论】:
以上是关于查询有或无日期约束的事件序列的主要内容,如果未能解决你的问题,请参考以下文章
Pandas:在两个不同时间序列中按日期顺序分组在同一 ID 下的列表中显示事件