SQL Server右表含重复值时如何关联表并计算订单履约提前期
门店订单履约各阶段提前期统计方案
步骤1:提取每个订单各履约状态的首次记录
先对履约日志表做预处理,过滤出每个OnlineFulFillmentId下各状态的首次发生时间:
WITH FirstActionDates AS ( SELECT OnlineFulFillmentId, ActionStatus, ACTION_DATE AS FirstActionDate FROM ( SELECT OnlineFulFillmentId, ActionStatus, ACTION_DATE, -- 按履约ID+状态分组,取最早的一条记录 ROW_NUMBER() OVER (PARTITION BY OnlineFulFillmentId, ActionStatus ORDER BY ACTION_DATE ASC) AS RowNum FROM [OnlineFulFillmentActionLogs] ) t WHERE RowNum = 1 )
步骤2:将各状态时间转为列(透视处理)
把分散的状态记录转成一行多列的格式,方便后续计算阶段差值:
, PivotedActionDates AS ( SELECT OnlineFulFillmentId, -- 替换成你系统中实际的履约状态值,比如'已接单'、'已备货'、'已配送'、'已完成' MAX(CASE WHEN ActionStatus = '已接单' THEN FirstActionDate END) AS 接单时间, MAX(CASE WHEN ActionStatus = '已备货' THEN FirstActionDate END) AS 备货时间, MAX(CASE WHEN ActionStatus = '已配送' THEN FirstActionDate END) AS 配送时间, MAX(CASE WHEN ActionStatus = '已完成' THEN FirstActionDate END) AS 完成时间 FROM FirstActionDates GROUP BY OnlineFulFillmentId )
步骤3:关联现有视图并计算各阶段提前期
将处理后的履约时间表和你的视图关联,计算相邻状态间的小时级提前期:
SELECT v.ORDER_NR, v.Id, -- 用ISNULL处理状态缺失的情况,按需返回0或NULL ISNULL(DATEDIFF(HOUR, pad.接单时间, pad.备货时间), 0) AS 接单到备货提前期(小时), ISNULL(DATEDIFF(HOUR, pad.备货时间, pad.配送时间), 0) AS 备货到配送提前期(小时), ISNULL(DATEDIFF(HOUR, pad.配送时间, pad.完成时间), 0) AS 配送至完成提前期(小时) FROM YourExistingView v -- 这里假设视图的Id和履约日志的OnlineFulFillmentId是关联键,按需调整 LEFT JOIN PivotedActionDates pad ON v.Id = pad.OnlineFulFillmentId
注意事项
- 替换
YourExistingView为你实际使用的视图名称 - 务必将
ActionStatus的取值替换成你系统中真实的履约状态标识(字符串/编码均可) - 如果需要按分钟/天计算提前期,修改
DATEDIFF的第一个参数为MINUTE或DAY - 使用
LEFT JOIN可保留视图中所有订单;若只需统计有履约记录的订单,改用INNER JOIN
内容的提问来源于stack exchange,提问作者Tiago
相关产品推荐
相关产品推荐

