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