SQL 服务器:为结束日期添加计算列

SQL Server: adding a calculated column for end date

我有一个数据集不断更新,日期值如下所示:

Part Number Product Status  Phase1  Phase2  Phase3  Phase4  Phase5  Phase6
FD 2000 Maintain    2020-01-03 00:00:00.000 2020-01-08 00:00:00.000 2020-01-15 00:00:00.000 2020-01-17 00:00:00.000 2020-01-22 00:00:00.000 2020-01-31 00:00:00.000
FD 2001 Maintain    2020-01-03 00:00:00.000 2020-01-08 00:00:00.000 2020-01-15 00:00:00.000 2020-01-17 00:00:00.000 2020-01-22 00:00:00.000 2020-01-31 00:00:00.000

基本上,table 由零件号及其各自的状态和生命周期日期组成。

然后,我利用CROSS APPLY将不同相列转置为一列。这是 SQL 语法:

SELECT [Part Number], [Product Status], Phase, Date
FROM PLCMexample
CROSS APPLY (VALUES ('Phase1', [Phase1]),
                    ('Phase2', [Phase2]),
                    ('Phase3', [Phase3]),
                    ('Phase4', [Phase4]),
                    ('Phase5', [Phase5]),
                    ('Phase6', [Phase6]))
            CrossApplied (Phase, Date)
GO

这会生成此视图:

Part Number Product Status  Phase   Date
FD 2000     Maintain    Registration Initiation 2020-01-03 00:00:00.000
FD 2000     Maintain    Product Launch  2020-01-08 00:00:00.000
FD 2000     Maintain    Phase Out   2020-01-15 00:00:00.000
FD 2000     Maintain    Last Order  2020-01-17 00:00:00.000
FD 2000     Maintain    Last Shipment   2020-01-22 00:00:00.000
FD 2000     Maintain    Last Service    2020-01-31 00:00:00.000
FD 2001     Maintain    Registration Initiation 2020-01-03 00:00:00.000
FD 2001     Maintain    Product Launch  2020-01-08 00:00:00.000
FD 2001     Maintain    Phase Out   2020-01-15 00:00:00.000
FD 2001     Maintain    Last Order  2020-01-17 00:00:00.000
FD 2001     Maintain    Last Shipment   2020-01-22 00:00:00.000
FD 2001     Maintain    Last Service    2020-01-31 00:00:00.000

一切都很好,但现在我不仅需要视图的 Date 列,还需要 StartDateEndDateStartDate 将是当前 Date 列中的值。 EndDate 与下一阶段的 StartDate 相同 Date。这是视图的前六行,作为其外观示例:

Part Number Product Status  Phase   StartDate   EndDate
FD 2000 Maintain    Registration Initiation 2020-01-03 00:00:00.000 2020-01-08 00:00:00.000
FD 2000 Maintain    Product Launch  2020-01-08 00:00:00.000 2020-01-15 00:00:00.000
FD 2000 Maintain    Phase Out   2020-01-15 00:00:00.000 2020-01-17 00:00:00.000
FD 2000 Maintain    Last Order  2020-01-17 00:00:00.000 2020-01-22 00:00:00.000
FD 2000 Maintain    Last Shipment   2020-01-22 00:00:00.000 2020-01-31 00:00:00.000
FD 2000 Maintain    Last Service    2020-01-31 00:00:00.000 2020-01-31 00:00:00.000

如您所见,“注册启动”EndDate与“产品发布”StartDate相同。最后一个阶段“Last Service”将具有相同的 StartDateEndDate

处​​理此问题的最佳方法是什么?我应该在转置之前还是之后创建计算列?这只是一个片段,有几千行数据就是这样,所以我想优化代码。

我想你想要 lead():

SELECT [Part Number], [Product Status], Phase, Date,
       LEAD(Date) OVER (PARTITION BY [Part Number] ORDER BY Date) as Next_Date
FROM PLCMexample CROSS APPLY
     (VALUES ('Phase1', [Phase1]),
             ('Phase2', [Phase2]),
             ('Phase3', [Phase3]),
             ('Phase4', [Phase4]),
             ('Phase5', [Phase5]),
             ('Phase6', [Phase6])
     ) CrossApplied (Phase, Date);

编辑:

如果需要默认值,请使用 LEAD() 的 3 参数形式:

       LEAD(Date, 1, DATEADD(DAY, 100, DATE) OVER (PARTITION BY [Part Number] ORDER BY Date) as Next_Date