1

Begindate (日時) と Enddate (日時) を持つデータベース テーブルがあります。この表には、活動期間が含まれています。現在、指定された開始日から終了日までの重複しないアクティビティに基づいて合計期間を計算する関数を作成しようとしています。

例は次のようになります。

パラメータを指定してこの関数を呼び出しています: Begindate='2012-08-16 10:00' Enddate='2012-08-16 18:00'

ここで、次のデータがテーブルにあるとします。

  1. begin: '2012-08-15 10:00' end '2012-08-15 14:00' (合計 4 時間)
  2. begin: '2012-08-16 09:00' end '2012-08-16 11:00' (合計 2 時間)
  3. begin: '2012-08-16 10:30' end '2012-08-16 10:45' (合計 15 分)
  4. begin: '2012-08-16 12:00' end '2012-08-16 16:00' (合計 4 時間)
  5. begin: '2012-08-16 13:00' end '2012-08-16 17:00' (合計 4 時間)
  6. begin: '2012-08-16 16:30' end '2012-08-16 16:45' (合計 15 分)
  7. begin: '2012-08-16 17:30' end '2012-08-16 20:00' (合計 2 時間 30 分)

今、私は次のことが起こるのが大好きです:

  1. 最初のアクティビティは指定された期間外であるため、含まれません。
  2. 部分一致なので、これは 1 時間を返します。
  3. アクティビティは 2 番目のアクティビティ内にあるため、含まれません。
  4. 期間内は4時間が含まれます。
  5. 16:00~17:00までの1時間
  6. アクティビティは含まれません。
  7. 指定された時間内に 30 分しかないため、それが含まれます。

返される合計は、6 時間 30 分です。

誰かがこれで私を助けることができれば、私はとても感謝しています! :)

4

1 に答える 1

3

不足している範囲を計算してから、完全な期間から期間を差し引く方が簡単な場合があります。

declare @begindate datetime = '20120816 10:00:00'
declare @enddate datetime = '20120816 18:00:00'

; with supplement as (
  select begindate, enddate
    from daterangetable
      -- overlapping ranges only
   where begindate <= @enddate
     and enddate >= @begindate
  union all
  -- empty start range to catch missing start intervals
  select @begindate, @begindate
  union all
  -- empty end range to catch missing end intervals
  select @enddate, @enddate
)
select datediff (minute, @begindate, @enddate)
     - sum (datediff (minute, gapStart, gapEnd)) Minutes
from
(
  select max(d2.enddate) gapStart, 
         d1.begindate gapEnd
    from supplement d1
   cross join supplement d2
      -- d2 range must start before d1 range
   where d2.begindate < d1.begindate
   group by d1.begindate
      -- Range is completely covered if d2 ends after d1 begins
      -- so it should be removed
  having max(d2.enddate) < d1.begindate
) missingRanges

最初の範囲の終了が 2 番目の範囲の開始より後であり、最初の範囲の開始が 2 番目の範囲の終了の前である場合、2 つの範囲が重複します。(はるかに優れた)説明については、リンクを参照してください。

Sql Server 2005 以降を使用していない場合は、コードwithを補足 d1 および補足 d2 の派生テーブルに移動する必要があります。

そして、これがSql Fiddle with exampleです。

于 2012-08-16T09:48:44.060 に答える