我需要帮助(为了更好地理解,请参见附图),因为我完全无助.
如你所见,我有用户,他们将我们的开始和结束日期时间存储在我的数据库中,如YYYY-mm-dd H:i:s.现在我需要根据最常见的时间范围重叠(对于大多数用户)找出所有用户的重叠.我想为大多数用户提供3个最常访问的数据时间重叠.我该怎么做?
我不知道我应该使用哪个mySQL查询,或者最好从数据库中选择所有日期时间(开始和结束)并在PHP中处理它(但是如何?).如图所示,结果应该是例如时间8.30-10.00是用户A B C D的结果.
Table structure: UserID | Start datetime | End datetime -------------------------------------- A | 2012-04-03 4:00:00 | 2012-04-03 10:00:00 A | 2012-04-03 16:00:00 | 2012-04-03 20:00:00 B | 2012-04-03 8:30:00 | 2012-04-03 14:00:00 B | 2012-04-06 21:30:00 | 2012-04-06 23:00:00 C | 2012-04-03 12:00:00 | 2012-04-03 13:00:00 D | 2012-04-01 01:00:01 | 2012-04-05 12:00:59 E | 2012-04-03 8:30:00 | 2012-04-03 11:00:00 E | 2012-04-03 21:00:00 | 2012-04-03 23:00:00
你实际拥有的是一组集合,并希望确定它们中是否有任何非交叉点.这是在尝试查找嵌套集中节点的所有祖先时要求的确切问题.
原文链接:https://www.f2er.com/php/136126.html我们可以证明,对于每个重叠,至少一个时间窗口将具有落在所有其他重叠时间窗口内的开始时间.使用这个小窍门,我们不需要在当天真正构建人工时段.只需要一个开始时间,看看它是否与任何其他时间窗口相交,然后只计算交叉点的数量.
那么查询是什么?
/*SELECT*/ SELECT DISTINCT MAX(overlapping_windows.start_time) AS overlap_start_time,MIN(overlapping_windows.end_time) AS overlap_end_time,(COUNT(overlapping_windows.id) - 1) AS num_overlaps FROM user_times AS windows INNER JOIN user_times AS overlapping_windows ON windows.start_time BETWEEN overlapping_windows.start_time AND overlapping_windows.end_time GROUP BY windows.id ORDER BY num_overlaps DESC;
根据您的表大小以及您计划运行此查询的频率,可能值得在其上删除空间索引(请参见下文).
UPDATE
如果经常运行此查询,则需要使用空间索引.由于基于范围的遍历(即start_time落在开始/结束范围之间),BTREE索引不会为您做任何事情.它必须是空间的.
ALTER TABLE user_times ADD COLUMN time_windows GEOMETRY NOT NULL DEFAULT 0; UPDATE user_times SET time_windows = GeomFromText(CONCAT('LineString( -1 ',start_time,',1 ',end_time,')')); CREATE SPATIAL INDEX time_window ON user_times (time_window);
然后,您可以更新上述查询中的ON子句以进行读取
ON MBRWithin( Point(0,windows.start_time),overlapping_windows.time_window )
这将为您提供查询的索引遍历.如果您经常计划运行查询,请再次执行此操作.
将空间指数归功于Quassoni’s blog.