2

特定のタイムシフトで働くためにサインアップした人々を示す「Volunteers」と呼ばれる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 に答える