-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. 将所有开始日期和结束日期放入一个列表中,并仅提取不同的日期。

  3. 让每两个日期彼此相邻以形成一个新范围。

  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
;

这是上述实现的SQL Fiddle 演示。

于 2013-02-06T09:10:12.620 回答