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的情况。