假设我有一个名为“志愿者”的mysql表,它显示已注册工作特定时间段的人员:
Volunteers
==============
**UserId** int
**StartTime** datetime
**EndTime** datetime
假设此表包含以下记录:
(1, '2012-01-01 00:00:00', '2012-01-01 01:00:00')
(2, '2012-01-01 00:00:00', '2012-01-01 00:30:00')
(3, '2012-01-01 00:30:00', '2012-01-01 01:00:00')
(4, '2012-01-01 00:00:00', '2012-01-01 00:15:00')
(5, '2011-12-31 23:00:00', '2012-01-01 02:00:00')
(6, '2012-01-01 00:00:00', '2012-01-01 00:00:30')
(7, '2012-01-01 00:00:00', '2012-01-01 00:40:00')
(8, '2012-01-01 00:20:00', '2012-01-01 01:00:00')
我想计算此表中用户已从00:00:00到01:00:00注册工作的所有记录,但还包括此计数时间段,可以汇总到此期望的时间段。
例如,使用上面的示例,理想的SQL查询将返回 4 。
说明:
用户1已注册以完成所需的整个班次,因此这会使计数增加1。
用户2和3已经注册了工作时移,这些时间段会聚合到所需的时移 这会增加1来计算。
用户4的时移不能与其他用户的时间转移聚合以覆盖所需的时移,因此这不会增加计数。
用户5涵盖了整个所需的时移,因此计数增加了1。
用户6有一个时间转换,可以与用户8的时移进行聚合以覆盖所需的时移,因此这会使计数增加1。
用户7具有可以与用户8的时移聚合以覆盖期望的时移的时移,但是如果用户8已经与用户6聚合以产生期望的时移,则该时移不应该包括在计数中。因此,这不会添加到计数中。
因此,计数等于4.
你会怎么做呢?这甚至可能吗?
答案 0 :(得分:1)
我认为您的问题不适合用SQL完全解决。以下是我将如何解决它。
选择所有与您感兴趣的班次重叠的志愿者。
在您的应用程序层(php / .NET / perl / whatever)中,然后应用此算法:
对这些间隔进行排序,然后将它们拆分为子间隔,使它们全部不相交或相等。
计算每种类型的相等子间隔数。
此计数的最小值是您的答案。