求助:查询另一表最小联系时间前的最大订单时间及订单状态
问题分析与解决方案
你的原查询返回多行的核心原因是:将order_status_id和status_description加入了分组条件,这会让每个符合时间条件的状态记录单独成组,自然无法得到每个订单仅一行的结果。要实现需求,需要先定位到每个订单在最小Contact_time之前的最新状态记录,再关联状态描述表,以下是两种可行方案:
方案一:窗口函数法(推荐)
利用ROW_NUMBER()窗口函数,按订单分组后筛选出联系时间前的最新状态:
WITH order_status_filtered AS ( SELECT os.Order_ID, os.order_status_id, os.Timestamp, ct.Contact_time, -- 按订单分组,仅保留联系时间前的记录,按时间倒序排名 ROW_NUMBER() OVER (PARTITION BY os.Order_ID ORDER BY os.Timestamp DESC) AS rn FROM Order_Status os JOIN Contact ct ON os.Order_ID = ct.Order_id WHERE os.Timestamp < ct.Contact_time ) SELECT osc.Order_ID, osc.order_status_id, ms.status_description, osc.Timestamp AS beforeContact FROM order_status_filtered osc LEFT JOIN meta_status ms ON osc.order_status_id = ms.order_status_id WHERE osc.rn = 1;
方案二:子查询法
先通过子查询计算每个订单在联系时间前的最大时间戳,再关联回订单状态表匹配对应状态:
SELECT os.Order_ID, os.order_status_id, ms.status_description, os.Timestamp AS beforeContact FROM Order_Status os JOIN ( -- 先获取每个订单的联系时间,以及该订单在联系前的最大时间戳 SELECT ct.Order_id, MAX(os.Timestamp) AS max_before_time FROM Contact ct JOIN Order_Status os ON ct.Order_id = os.Order_ID WHERE os.Timestamp < ct.Contact_time GROUP BY ct.Order_id ) pre ON os.Order_ID = pre.Order_id AND os.Timestamp = pre.max_before_time LEFT JOIN meta_status ms ON os.order_status_id = ms.order_status_id;
两种方案最终都会返回4行结果,分别对应订单1、2、4、5的目标状态数据。
内容的提问来源于stack exchange,提问作者Syed Ariff
相关产品推荐
相关产品推荐

