Sql 基于列克隆行

Sql 基于列克隆行,sql,sql-server,Sql,Sql Server,我的数据如下所示: ID Duration Start Date End Date ------------------------------------------------------ 10 2 2013-09-03 05:00:00 2013-09-03 05:02:00 我需要如下输出: 10 2 2013-09-03 05:00:00 2013-09-03 05:01:00 1 10 2 2013-09

我的数据如下所示:

ID  Duration  Start Date          End Date
------------------------------------------------------
10  2         2013-09-03 05:00:00 2013-09-03 05:02:00
我需要如下输出:

10  2        2013-09-03 05:00:00 2013-09-03 05:01:00  1  
10  2        2013-09-03 05:01:00 2013-09-03 05:02:00  2
基于列持续时间,如果值为2,则需要将行复制两次

如果我们在输出中看到开始日期和结束日期,时间应该相应地改变

在上面显示的1/2的情况下,行数作为复制行数的附加列将有很大帮助

如果持续时间为0和1,则不执行任何操作,只有当持续时间>1时,才复制行。
最后是数字行序列1、2、3的附加列,用于显示有多少行被复制。

试试下面的sql,我在我认为必要的地方添加了一些注释

declare @table  table(Id integer not null, Duration int not null, StartDate datetime, EndDate datetime)

insert into @table values (10,2, '2013-09-03 05:00:00', '2013-09-03 05:02:00')
insert into @table values (11,3, '2013-09-04 05:00:00', '2013-09-04 05:03:00')



;WITH 
 numbers AS (
--this is the number series generator 
--(limited to 1000, you can change that to whatever you need
-- max possible duration in your case).
    SELECT 1 AS num
    UNION ALL
    SELECT num+1 FROM numbers WHERE num+1<=100
)
SELECT t.Id
    , t.Duration
    , StartDate = DATEADD(MINUTE, IsNull(Num,1) - 1, t.StartDate)
    , EndDate = DATEADD(MINUTE, IsNull(Num,1), t.StartDate)
    , N.num
FROM @table t
LEFT JOIN numbers N
    ON t.Duration >= N.Num
-- join it with numbers generator for Duration times
ORDER BY t.Id
    , N.Num

当持续时间=0时,这种方法效果更好:

declare @table  table(Id integer not null, Duration int not null, StartDate datetime, EndDate datetime)

insert into @table values (10,2, '2013-09-03 05:00:00', '2013-09-03 05:02:00')
insert into @table values (11,3, '2013-09-04 05:00:00', '2013-09-04 05:03:00')
insert into @table values (12,0, '2013-09-04 05:00:00', '2013-09-04 05:03:00')
insert into @table values (13,1, '2013-09-04 05:00:00', '2013-09-04 05:03:00')
;WITH 
 numbers AS (
--this is the number series generator 
--(limited to 1000, you can change that to whatever you need
-- max possible duration in your case).
    SELECT 1 AS num
    UNION ALL
    SELECT num+1 FROM numbers WHERE num+1<=100
)
SELECT 
      Id
    , Duration
    , StartDate
    , EndDate 
    , num
FROM 
(SELECT 
      t.Id
    , t.Duration
    , StartDate = DATEADD(MINUTE, Num - 1, t.StartDate)
    , EndDate = DATEADD(MINUTE, Num, t.StartDate)
    , N.num
FROM @table t
INNER JOIN numbers N
    ON t.Duration >= N.Num ) A
-- join it with numbers generator for Duration times
UNION 
(SELECT 
      t.Id
    , t.Duration
    , StartDate-- = DATEADD(MINUTE, Num - 1, t.StartDate)
    , EndDate --= DATEADD(MINUTE, Num, t.StartDate)
    , 1 AS num
FROM @table t
WHERE Duration = 0)
ORDER BY Id,Num

你不能用存储过程来实现这一点吗?我是SQL的新手,需要帮助。请:如果你是新手,这很有挑战性:如果有人能帮忙,我可以解决这个挑战。最长的持续时间是什么?非常感谢你!。按照我的要求,它工作得很好。非常感谢您的帮助::Hazimdekenli您能详细解释一下这个条件吗t.Duration>=N.NumDuration是您希望它重复的次数,因此它将匹配等于或小于Duration的数字,即1。。Duration@max请将其标记为答案,如果你认为这就是答案。@Hazimdekenli如何让Duration\u new这样的新列以一分钟的分辨率显示Duration的值,而不是Duration的总和?示例:id Duration\u New。。。。。10 11 11 11 11我编辑了我的原始查询以处理持续时间=0的情况。