2

假设我有一个名为“志愿者”的 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。

你会怎么做呢?这甚至可能吗?

4

1 回答 1

1

我认为您的问题不适合用 SQL 完全解决。这是我将如何解决它。

选择与您感兴趣的班次重叠的所有志愿者。

然后在您的应用程序层(php/.NET/perl/whatever)中应用此算法:

  1. 对这些区间进行排序,并将它们拆分为子区间,使它们全部不相交或相等。

  2. 计算每种类型的相等子区间的数量。

  3. 这个计数的最小值就是你的答案。

于 2012-12-09T03:35:04.903 回答