SQL Server 2016 根据其他记录修改列

SQL Server 2016 modifying column based on other record

我在根据产品到达时间和有能力开始组装的开始日期计算时遇到问题。这是假设一次只能在给定位置组装一个 product/part。没有零件必须到达才能开始组装的特定顺序。

可用数据:

Product  Part  HardwareArrival Location    AssemblyDays 
A        1A    2018-01-01      Facility A  12          
A        2A    2018-01-02      Facility A  12            
A        3A    2018-01-03      Facility A  12             
B        1A    2018-01-04      Facility B  9              
B        2A    2018-01-05      Facility B  9              
B        3A    2018-01-06      Facility B  9             

期望的结果:

Product  Part  HardwareArrival Location    AssemblyDays   StartOfAssembly
A        1A    2018-01-01      Facility A  12             2018-01-01
A        2A    2018-01-02      Facility A  12             2018-01-13
A        3A    2018-01-03      Facility A  12             2018-01-25
B        1A    2018-01-04      Facility B  9              2018-01-04
B        2A    2018-01-05      Facility B  9              2018-01-13
B        3A    2018-01-06      Facility B  9              2018-01-22

您可以使用 递归 CTE:

;WITH RnCTE AS (
    -- Assign a row number to each part within each 'Location' slice
    SELECT Product, Part, HardwareArrival, Location, AssemblyDays,
           ROW_NUMBER() OVER (PARTITION BY Location ORDER BY HardwareArrival) AS rn
    FROM mytable
), StartOfAssemblyCTE AS (
    -- Anchor member: get the first part to be assembled for each 'Location'
    SELECT Product, Part, HardwareArrival, Location, AssemblyDays, 
           rn AS level,
           HardwareArrival AS StartOfAssembly
    FROM RnCTE
    WHERE rn = 1

    UNION ALL

    -- Recursive member: Get next start date
    SELECT t1.Product, t1.Part, t1.HardwareArrival, t1.Location, t1.AssemblyDays, 
           t1.rn AS level,
           -- If hardware arrival for current part is later than 'start-of-assembly'
           -- calculated based on AssemblyDays and preceding start date, 
           -- then select hardware arrival date as starting date
           CASE 
              WHEN x.StartOfAssembly < t1.HardwareArrival THEN t1.HardwareArrival
              ELSE StartOfAssembly 
           END AS StartOfAssembly 
    FROM RnCTE AS t1
    JOIN StartOfAssemblyCTE AS t2 ON t1.Location = t2.Location AND t1.rn = t2.level + 1
    CROSS APPLY (SELECT DATEADD(dd, 
                                t1.AssemblyDays, 
                                t2.StartOfAssembly)) AS x(StartOfAssembly)
    WHERE rn = level + 1
)
SELECT Product, Part, HardwareArrival, Location, AssemblyDays, StartOfAssembly
FROM StartOfAssemblyCTE
ORDER BY Location, HardwareArrival

Demo here