2012-04-23 11 views
1

これは(MS SQL Server 2008)です。ユーザーは、重複することなく開始日と終了日の他のユーザーをスケジュールすることができます。SQL、日付/時刻の選択

スケジュール中に個人を重複させることができないというビジネスルールに取り組んでいます。 E.G、ユーザー1が2012年1月1日から2012年1月4日に予定されている場合、ユーザー2は2012年1月20日から2012年1月4日のリクエストを送信できません。この部分はすでに処理されており、ここに私のSQLがあります。

SELECT * FROM fooTable 
WHERE 
    Prim = 1 
AND 
    Group = 10 
AND 
    (('2012-06-01 08:01' between startdate and enddate 
    OR '2012-06-03 08:01' between startdate and enddate) 
OR 
    ('2012-06-01 08:01' < startdate) AND ('2012-06-03 8:01' > enddate)) 

私は、新しいシフトが最後のものが終わるときに開始することができるという意味で、スケジュールを重複させる必要があります。 E.G、私の終了日は2012年1月1日午後8時です。私は誰かを2012年1月1日と午後8時に開始するようにスケジュールすることができます。

これを考えて助けが必要です。

+1

これは多くの場合データベース固有のもので、実際に使用している特定のRDBMS(Oracle、MySQLなど)で実際にタグ付けする必要があります。 – Ben

+0

開始日と終了日の完全な日付/時刻を格納して比較する場合は、同じロジックを使用しないでください。 「1/1/2012 20:00」の開始時刻は、「1/1/2012 20:00」の終了時刻と重複してはならない。 – mellamokb

答えて

3

まず、カラム名としてGroupを使用しないでください。これはすべてのSQL標準で予約語です。私はそれを私の答えの目的でgrpに改名しました。 '2012-06-03 08:00'から'2012-06-01 08:00'から新しいシフトをスケジュールしようとすると

...

INSERT INTO tbl (prim, grp, startdate, enddate) 
SELECT 1, 10, '2012-06-01 08:00', '2012-06-03 08:00' 
WHERE NOT EXISTS (
    SELECT * 
    FROM tbl 
    WHERE prim = 1 
    AND grp = 10 
    AND '2012-06-03 08:00' > startdate -- not >= to allow sharing a border 
    AND '2012-06-01 08:00' < enddate -- and not BETWEEN ... AND either 
    ) 

私は比較注:

 
new_end > old_start 
new_start < old_end 

あなたがBETWEEN .. AND ..を使用する場合は、あなたのテストのシフトの境界が含まれます。 >=<=と同じです。境界が重なるようにするには、><を使用する必要があります。

さて、私の大幅に単純化された構文を試してみてください。あなたが元々持っていたものについてはわからない。
ここにはworking demo on sqlfiddle.comがあります。

+0

また、DBにレコードがあり、開始時刻が2012年1月1日と2012年1月7日の終了日 - 2011年12月31日と2012年1月8日に新しい投稿を送信した場合でも、誰かが既にそのスケジュールをカバーしているとエラーが表示されます。私はその部分を私のクエリに組み込んだので、2番目のOR文があったのです。 –

+0

@JasonWells:私のクエリはそれを行います。それを試してみてください!重複するすべてのケースをカバーする必要があります。 'SELECT'を' INSERT'と組み合わせることができない場合は、私の答えから 'SELECT'を取ってください。 –

+0

+1のグループキーワードと重複のテクニック – Simon