STL*_*Dev 1 sql-server t-sql sql-server-2008-r2
我有以下形式的数据需要合并,以便我从两行输入数据创建一行,其中第二列是下一行减去一天的值。
我一直在努力想出一种方法来做到这一点,但没有走得太远。我希望这张图能解释这个问题:
表结构
CREATE TABLE Process(
ProcessOrder int NOT NULL IDENTITY (1, 1),
ProcessDate date NOT NULL
);
Run Code Online (Sandbox Code Playgroud)
询问
SELECT ProcessOrder, ProcessDate From Process ORDER BY ProcessOrder;
Run Code Online (Sandbox Code Playgroud)
数据
ProcessOrder ProcessDate
------------ -----------
208 2016-01-04
209 2016-01-11
210 2016-01-18
211 2016-01-25
212 2016-02-01
213 2016-02-08
Run Code Online (Sandbox Code Playgroud)
我需要将上述数据变成以下形状(注意,从后续记录来看,ProcessEnd 比 ProcessBegin 少一天):
ProcessOrder ProcessBegin ProcessEnd
------------ ------------ ----------
208 2016-01-04 2016-01-10
209 2016-01-11 2016-01-17
210 2016-01-18 2016-01-24
211 2016-01-25 2016-01-31
212 2016-02-01 2016-02-07
213 2016-02-08 *NULL*
Run Code Online (Sandbox Code Playgroud)
编辑
我保证 ProcessOrder 列中的值是连续的,没有缺失值。
由于你是 2008 年,你还没有 LEAD 函数(我相信),所以你可以用 CTE 自己做:
WITH RankedProcess AS
(
SELECT ProcessOrder, ProcessDate, ROW_NUMBER() OVER(ORDER BY ProcessDate) AS Seq
FROM Process
)
SELECT P1.ProcessOrder, P1.ProcessDate AS ProcessBegin, DATEADD(day, -1, P2.ProcessDate) AS ProcessEnd
FROM RankedProcess AS P1
LEFT OUTER JOIN RankedProcess AS P2
ON P1.Seq = P2.Seq - 1
Run Code Online (Sandbox Code Playgroud)
在 2012 年及之后,您可以只使用 LEAD:
SELECT ProcessOrder, ProcessDate AS ProcessBegin, LEAD(DATEADD(day, -1, ProcessDate)) OVER(ORDER BY ProcessDate) AS ProcessEnd
FROM Process
Run Code Online (Sandbox Code Playgroud)
鉴于更新保证 ProcessOrder 是连续的且没有缺失值(并且我假设它们与日期的顺序相同),您可以无需使用 CTE,而只需使用 ProcessOrder 列。然而,CTE 的解决方案更为通用,我认为这仍然有用,因为我通常对数据库未强制执行的数据要求持怀疑态度。
| 归档时间: |
|
| 查看次数: |
15785 次 |
| 最近记录: |