我有如下所示的数据(当前数据)
e.g。
修改了NewDate
列显示 - 我们是否可以按照所需输出数据集的要求显示Newdate
列?
当前数据
ID NAME START END TRAVELDATE
===============================================================
1 TOM 1/15/13 12/6/13 1/25/13
1 TOM 1/15/13 12/6/13 2/2/13
1 TOM 1/15/13 12/6/13 3/1/13
期望的输出
ID NAME START END TRAVELDATE NEWDATE
========================================================================
1 TOM 1/15/13 12/6/13 1/25/13 1/15/13 - 1/30/13
1 TOM 1/15/13 12/6/13 2/2/13 1/30/13 - 2/14/13
1 TOM 1/15/13 12/6/13 3/1/13 2/14/13 - 3/1/13
答案 0 :(得分:2)
您可以使用ROW_NUMBER()
功能和DATEADD()
:
SELECT *,DATEADD(day,ROW_NUMBER()OVER(ORDER BY TravelDate)*15,Start) NewDate
FROM Table1
演示:SQL Fiddle
如果您的示例不全面,可能需要进行调整,即如果Start
日期实际上可以更改,那么您希望将第一个Start
值加载到变量中并将其用于DATEADD()
函数,而不是引用每行的Start
值。
答案 1 :(得分:1)
制作一些测试数据:
DECLARE @Travel TABLE
(
ID INT,
NAME VARCHAR(20),
STARTDT DATE,
ENDDT DATE,
TRAVELDATE DATE
)
INSERT INTO @Travel
VALUES
(1, 'TOM', '1/15/13', '12/6/13', '1/25/13'),
(1, 'TOM', '1/15/13', '12/6/13', '2/2/13'),
(1, 'TOM', '1/15/13', '12/6/13', '3/1/13');
现在我们使用行号来确定我们的序列,然后对每条记录使用序列* 15天:
SELECT *,
DATEADD(DAY, 15 * RN, STARTDT) NEWDATE
FROM
(
SELECT *,
ROW_NUMBER() OVER (ORDER BY TravelDate) RN
FROM @Travel
) d
这是输出:
ID NAME STARTDT ENDDT TRAVELDATE RN NEWDATE
1 TOM 2013-01-15 2013-12-06 2013-01-25 1 2013-01-30
1 TOM 2013-01-15 2013-12-06 2013-02-02 2 2013-02-14
1 TOM 2013-01-15 2013-12-06 2013-03-01 3 2013-03-01
以下是所要求的更新版本:
SELECT *,
DATEADD(DAY, 15 * (RN - 1), STARTDT) STARTNEWDATE,
DATEADD(DAY, 15 * RN, STARTDT) ENDNEWDATE
FROM
(
SELECT *,
ROW_NUMBER() OVER (ORDER BY TravelDate) RN
FROM @Travel
) d
以下是修改后的输出:
ID NAME STARTDT ENDDT TRAVELDATE RN STARTNEWDATE ENDNEWDATE
1 TOM 2013-01-15 2013-12-06 2013-01-25 1 2013-01-15 2013-01-30
1 TOM 2013-01-15 2013-12-06 2013-02-02 2 2013-01-30 2013-02-14
1 TOM 2013-01-15 2013-12-06 2013-03-01 3 2013-02-14 2013-03-01
答案 2 :(得分:0)
这听起来像是递归CTE的一个很好的候选者。
WITH c AS (
SELECT T.ID, NewDate
FROM #Test T
UNION ALL
SELECT T.ID, DATEADD(DAY, 15, c.NewDate)
FROM #Test T
JOIN c ON c.id = T.id
WHERE DATEADD(DAY, 15, c.NewDate) < '2015-12-31'
)
SELECT * FROM c
答案 3 :(得分:0)
我想你想要这样的东西
SELECT ID,NAME,START,[END],TRAVELDATE
, ROW_NUMBER() OVER (PARTITION BY NAME ORDER BY TRAVELDATE) as rowNo
, DATEADD(DAY,15,START) as newDate
INTO #TEMP
FROM START
;WITH c AS(
SELECT ID,NAME,START,[END],TRAVELDATE, NEWDATE, rowNo
FROM #TEMP T
where T.rowNo = 1
UNION ALL
SELECT t.ID,t.NAME,t.START,t.[END],t.TRAVELDATE, DATEADD(DAY,15,c.NEWDATE) as newDate, t.rowNo
FROM #TEMP T
JOIN c ON T.rowNo = c.rowNo+1
AND T.NAME = c.NAME
)
SELECT * FROM c
ORDER BY c.NAME, c.rowNo
如果您有多个名称并且想要从每个名称的开始日期开始,这种方法很有效。
有关详细信息,请参阅Sql Fiddle。