基于关联表条件,如何查询存在未响应开放请求的订单?
找出存在开放联系请求的订单
先把两张表的结构和数据整理清楚,方便理解问题:
Orders表
| ID | User |
|---|---|
| 1 | Matt |
| 2 | Chris |
| 3 | John |
Order_Contact表
| ID | Order_ID | Type | Timestamp |
|---|---|---|---|
| 1 | 1 | Request | 2018-01-01 10:00:00 |
| 2 | 1 | Request | 2018-01-01 10:35:00 |
| 3 | 1 | Response | 2018-01-01 11:00:00 |
| 4 | 1 | Request | 2018-01-01 12:00:00 |
| 5 | 2 | Request | 2018-01-01 13:00:00 |
| 6 | 2 | Response | 2018-01-01 14:00:00 |
需求里的开放请求定义很关键:请求时间之后没有响应记录,而且一条响应可以“覆盖”之前的所有请求。也就是说,只要某个订单里存在至少一个请求,在它之后没有任何响应(或者这个订单压根没有过响应),那这个订单就符合要求。
我的解决思路
- 先给每个订单统计出它最晚的响应时间——如果某个订单从来没有过响应,这个值就是
NULL - 然后筛选出那些有请求,且请求时间晚于最晚响应时间(或者没有响应)的订单
- 最后关联Orders表拿到对应的用户信息,用
DISTINCT避免重复记录
最终SQL语句
SELECT DISTINCT o.ID, o.User FROM Orders o INNER JOIN Order_Contact oc ON o.ID = oc.Order_ID LEFT JOIN ( -- 子查询:获取每个订单的最后响应时间 SELECT Order_ID, MAX(Timestamp) AS last_response_time FROM Order_Contact WHERE Type = 'Response' GROUP BY Order_ID ) resp ON o.ID = resp.Order_ID WHERE oc.Type = 'Request' AND ( -- 两种符合条件的情况:没有响应,或者请求时间晚于最后响应时间 resp.last_response_time IS NULL OR oc.Timestamp > resp.last_response_time );
执行结果
这条SQL会返回你预期的结果:
| ID | User |
|---|---|
| 1 | Matt |
解释一下:
- 订单1的最后响应是11:00,但之后还有一个12:00的Request,没有后续响应,所以符合条件
- 订单2的最后一条记录是Response,所有Request都有对应的后续响应,所以被排除
- 订单3没有任何联系记录,自然不存在开放请求,所以也不会出现在结果里
内容的提问来源于stack exchange,提问作者Pegaz
相关产品推荐
相关产品推荐

