我正在尝试编写一个查询,以便针对特定跨度重新排序日期范围。它应该做一些看起来像这样的事情
Row Rank Begin Date End Date
1 B 3/24/13 11/1/13
2 A 10/30/13 4/9/15
3 B 3/26/15 12/31/15
让它变成
Row Rank Begin Date End Date
1 B 3/24/13 10/29/13
2 A 10/30/13 4/9/15
3 B 4/10/15 12/31/15
为了进一步解释,第2行中的日期排名更高(A> B),因此第1行和第3行中的日期必须围绕第2行中的日期进行更改,以避免日期重叠。
我正在使用SQL Server 2008 R2
答案 0 :(得分:0)
请使用以下查询更新表格。
Update table_name
set End_Date = DATEADD(day, -1, select Begin_Date from Table_name where
Row_number = '2')
where row = 1;
每次运行查询时都需要更改行号。让我知道如果这适合你。
我建议先创建一个视图
CREATE OR REPLACE VIEW tempview AS
SELECT row, begin_date FROM table_name
WHERE row > 1;
然后使用此查询更新所有行。如果不能仅更新第一行。
Update table_name
set End_Date = DATEADD(day, -1, select Begin_Date from tempview)
希望这有效
答案 1 :(得分:0)
您可以使用以下查询:
;WITH CTE AS (
SELECT Row, Rank, BeginDate, EndDate,
ROW_NUMBER() OVER (ORDER BY BeginDate) AS rn
FROM mytable
), ToUpdate AS (
SELECT c1.Row, c1.Rank, c1.BeginDate, c1.EndDate,
c2.Rank AS pRank, c2.EndDate AS pEndDate,
c3.Rank AS nRank, c3.BeginDate AS nBeginDate
FROM CTE AS c1
LEFT JOIN CTE AS c2 ON c1.rn = c2.rn + 1
LEFT JOIN CTE AS c3 ON c1.rn = c3.rn - 1
WHERE c1.Rank = 'B'
)
UPDATE ToUpdate
SET BeginDate = CASE
WHEN pEndDate IS NULL
THEN BeginDate
WHEN (pEndDate >= BeginDate) AND (pRank = 'A')
THEN DATEADD(d, 1, pEndDate)
ELSE BeginDate
END,
EndDate = CASE
WHEN nBeginDate IS NULL
THEN EndDate
WHEN (nBeginDate <= EndDate) AND (nRank = 'A')
THEN DATEADD(d, -1, nBeginDate)
ELSE EndDate
END
最初构建CTE
以将连续的升序编号分配给表的每个记录。 ROW_NUMBER()
窗口函数用于此目的。
使用此CTE
作为基础,我们构建ToUpdate
。后者CTE
包含当前的日期值以及上一个和下一个记录。
这LEFT JOIN
:
LEFT JOIN CTE AS c2 ON c1.rn = c2.rn + 1
用于与之前的记录连接在一起,而这一个:
LEFT JOIN CTE AS c3 ON c1.rn = c3.rn - 1
用于与 next 记录一起加入。
使用CASE
表达式,我们现在可以轻松识别重叠,如果有,则执行更新。