2

我有这样的记录:

start, end , total  
 830 , 1300,   5
 1400, 1430,   2

我想扩展到:

instance , total  
  830    ,   5
  831    ,   5
  832    ,   5
  ...
  1299   ,   5
  1300   ,   5

  1400   ,   2
  1401   ,   2
  ...
  1429   ,   2
  1430   ,   2

如何在 MSSQL 2005 中使用 SQL 执行此操作?

编辑:谢谢大家,很好的答案。有几个工作。我只是忘了说虽然开始/结束实际上是一个存储为 int 的时间,所以 0830 到 1300 应该上升到 0859 然后 0900。我不能指望你们在同一个问题上回答这个问题,我会工作周围。再次感谢

4

3 回答 3

1

这应该可以解决问题:

create table input (start int, [end] int, total int)

insert input values (830, 1300, 5)
insert input values (1400, 1430, 2)

declare @output table (instance int, start int, [end] int, total int)

insert @output select start, start, [end], total from input

while @@rowcount > 0
    insert @output
    select
        max(instance) + 1,
        start,
        [end],
        total
    from @output
    group by
        start,
        [end],
        total
    having max(instance) < [end]

select instance, total from @output order by instance

这会输出与您在问题中描述的相同(未截断)的结果。

可能有一些花哨的 CTE 方法,但我认为这行不通,因为您需要无限量的递归。

于 2010-08-16T15:00:36.560 回答
1

假设您的 END 值有一个有限的最大值,您可以使用数字表(将 2000 更改为您的最大 END 值):

declare @Test table (
    start int,
    [end] int,
    total int
)

insert into @Test
    (start, [end], total)
    select 830, 1300, 5
    union
    select 1400, 1430, 2

;WITH Nbrs ( n ) AS (
        SELECT 1 UNION ALL
        SELECT 1 + n FROM Nbrs WHERE n < 2000
)
select n.n, t.total
    from @Test t
        cross join Nbrs n
    where n.n between t.start and t.[end]
    option (MAXRECURSION 2000)
于 2010-08-16T15:03:30.450 回答
1

使用 CTE:

with number_cte(n) as 
 (select n from (select 0 n) m union all select n+1 n
  from number_cte where n< 2400)
select start+n instance, total
from 
datatable
join number_cte on start+n between start and [end]
where start+n - 100*floor((start+n)/100) between 0 and 59
order by 1
option (maxrecursion 2401)

(如果需要大于 2400 的范围,则酌情增加 n< ... 和 maxrecursion 数。)

编辑以防止包含无效的实例(即时间值在 60​​ 到 99 之间结束)值。

于 2010-08-16T15:06:25.590 回答