SQL Server 2016基于其他记录修改列

问题描述 投票:1回答:1

我有一个问题,计算产品可以根据它何时到达以及何时有能力开始组装而开始组装的开始日期。这假设在给定位置一次只能组装一个产品/部件。部件必须到达以开始组装没有特定的顺序。

可用数据:

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
sql sql-server dateadd
1个回答
0
投票

你可以使用递归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

© www.soinside.com 2019 - 2024. All rights reserved.