获取订单最后事件记录并通过CASE判断事件类型的SQL问题
解决方案
方法1:使用窗口函数筛选最后一条事件记录
通过ROW_NUMBER()窗口函数为每个OrderId下的事件按OrderEventId降序排序,取排序为1的那条(即最后一条事件),再关联TOrder表获取订单号,最后通过CASE判断事件类型。
SELECT o.OrderNumber, oe.OrderEventId AS LastOrderEventId, CASE oe.OrderEventTypeId WHEN 107 THEN 'T&R Delay' -- 可按需添加其他事件类型的判断逻辑 ELSE 'Other Status' END AS EventStatus FROM TOrder o INNER JOIN ( SELECT OrderId, OrderEventId, OrderEventTypeId, ROW_NUMBER() OVER (PARTITION BY OrderId ORDER BY OrderEventId DESC) AS rn FROM TOrderEvent ) oe ON o.OrderId = oe.OrderId WHERE oe.rn = 1;
方法2:先获取每个订单的最大事件ID,再关联详情
先通过CTE得到每个OrderId对应的最大OrderEventId,再关联TOrderEvent获取该事件的类型,最后关联TOrder表并完成状态判断。
WITH LastOrderEvents AS ( SELECT OrderId, MAX(OrderEventId) AS LastOrderEventId FROM TOrderEvent GROUP BY OrderId ) SELECT o.OrderNumber, loe.LastOrderEventId, CASE oe.OrderEventTypeId WHEN 107 THEN 'T&R Delay' ELSE 'Other Status' END AS EventStatus FROM TOrder o INNER JOIN LastOrderEvents loe ON o.OrderId = loe.OrderId INNER JOIN TOrderEvent oe ON loe.OrderId = oe.OrderId AND loe.LastOrderEventId = oe.OrderEventId;
关键说明
- 两种方法都确保每个
OrderId仅返回一行结果,且仅基于该订单的最后一条事件记录进行状态判断,彻底解决了之前只要订单存在107类型事件就错误返回状态的问题。 - 窗口函数方案在数据量较大时性能更优,仅需扫描
TOrderEvent表一次;第二种方案逻辑更直观,适合快速理解。 - 若需包含无事件记录的订单,可将
INNER JOIN改为LEFT JOIN,此时LastOrderEventId和EventStatus会返回NULL,可通过COALESCE设置默认值。
内容的提问来源于stack exchange,提问作者LogisticsRay
相关产品推荐
相关产品推荐

