-1

これが私の前提条件です。

user_id  | module_start_date | module_end_date | loading
 6       | 01-01-2013        | 31-01-2013      | 0.4
 6       | 16-01-2013        | 31-01-2013      | 0.2
 6       | 01-03-2013        | 15-03-2013      | 0.7
 6       | 30-01-2013        | 30-01-2013      | 0.5

図のように、読み込みを追加して日付範囲を変更する必要があります。同じstart_dateとend_dateを使用すると、上記の条件で直面している問題を追加できます。

注:-複数のユーザーがいる可能性があります。

user_id   |  module_start_date| module_end_date | loading
  6       | 01-01-2013        | 15-01-2013      | 0.4
  6       | 16-01-2013        | 29-01-2013      | 0.6
  6       | 30-01-2013        | 30-01-2013      | 1.1
  6       | 31-01-2013        | 31-01-2013      | 0.6
  6       | 01-03-2013        | 15-03-2013      | 0.7
4

1 に答える 1

0

終了日が排他的である場合、これは少し簡単になります。それにもかかわらず、ここに計画があります:

  1. すべての範囲で終了日を一時的に増やして、排他的にします。

  2. すべての開始日と終了日を1つのリストに入れ、個別の日付のみを取得します。

  3. 2つおきに日付を並べて、新しい範囲を作成します。

  4. 内側は、新しい範囲リストを終了日が増加したリストに結合し、新しい範囲でグループ化して、の合計を取得しloadingます。

  5. すべての終了日を1ずつ減らして、新しい範囲を元の「包括的」形式に変換します。

これは、上記の計画の実装です。

WITH converted AS (
  -- #1
  SELECT
    user_id,
    module_start_date,
    module_end_date = DATEADD(DAY, 1, module_end_date),
    loading
  FROM atable
),
datesranked AS (
  -- #2
  SELECT
    c.user_id,
    x.date,
    rnk = ROW_NUMBER() OVER (PARTITION BY c.user_id ORDER BY x.date)
  FROM converted AS c
  CROSS APPLY (
    VALUES (c.module_start_date), (c.module_end_date)
  ) AS x (date)
  GROUP BY
    c.user_id,
    x.date
),
newranges AS (
  -- #3
  SELECT
    d1.user_id,
    module_start_date = d1.date,
    module_end_date   = d2.date
  FROM
  datesranked AS d1
  INNER JOIN datesranked AS d2
    ON d1.user_id = d2.user_id
    AND d1.rnk = d2.rnk - 1
),
totals AS (
  -- #4 & #5
  SELECT
    new.user_id,
    new.module_start_date,
    module_end_date = DATEADD(DAY, -1, new.module_end_date),
    loading = SUM(old.loading)
  FROM newranges AS new
  INNER JOIN converted AS old
    ON new.user_id = old.user_id
    AND new.module_end_date > old.module_start_date
    AND new.module_start_date < old.module_end_date
  GROUP BY
    new.user_id,
    new.module_start_date,
    new.module_end_date
)
SELECT *
FROM totals
;

そして、これが上記の実装のSQLFiddleデモです。

于 2013-02-06T09:10:12.620 に答える