SQL查询实现:筛选无同客户后续记录的Sold状态客户
实现思路
需求的核心判定规则是:
- 记录本身的状态为
Sold - 对当前记录所属的客户,整个请求数据集中不存在任何请求日期晚于当前记录日期的同客户记录
只要满足这两个条件,就会被纳入返回结果,刚好对应示例里“客户HHH因为存在晚于旧Sold记录的其他请求,所以不返回;客户EEE的唯一记录就是最晚的,且状态为Sold,所以返回”的规则。
可落地的SQL实现方案
方案1:窗口函数实现(适配主流数据库,性能更优)
通过给每个客户的所有请求按请求日期倒序排名,直接取每个客户排名第一(即请求日期最晚)的记录,再叠加状态为Sold的过滤条件即可,逻辑清晰不会出现重复匹配问题。
WITH base_dataset AS ( -- 替换为你原有多表关联的基础查询逻辑 SELECT c.name AS CLIENT, r.requestDate AS REQUESTDATE, co.areaName AS COUNTRY, -- 匹配Countries表的实际国家字段 r.arrivalDate AS ARRIVAL, rs.statusName AS STATUS, -- 匹配RequestStatus表的实际状态字段 c.id AS client_uid -- 必须带客户唯一主键,避免重名客户误判 FROM Clients c INNER JOIN Requests r ON c.id = r.client_id INNER JOIN Countries co ON r.country_id = co.id INNER JOIN RequestClientEvent rce ON r.id = rce.request_id INNER JOIN RequestStatus rs ON r.status_id = rs.id WHERE r.arrivalDate >= '2020-01-01' ), client_date_rank AS ( -- 按客户分组,给记录按请求日期从晚到早排名 SELECT *, ROW_NUMBER() OVER ( PARTITION BY client_uid ORDER BY REQUESTDATE DESC ) AS rn FROM base_dataset ) SELECT CLIENT, REQUESTDATE, COUNTRY, ARRIVAL, STATUS FROM client_date_rank WHERE rn = 1 -- 只保留每个客户最晚的那条请求 AND STATUS = 'Sold' -- 保留你原有的排序、限制返回条数逻辑 ORDER BY CLIENT ASC, REQUESTDATE ASC, STATUS ASC LIMIT 10;
方案2:NOT EXISTS 判断(适配无窗口函数的老旧数据库)
直接在原有查询的过滤条件里加子查询判断,只要不存在同客户、请求日期大于当前记录的其他请求,就符合“无后续关联记录”的要求。
SELECT c.name AS CLIENT, r.requestDate AS REQUESTDATE, co.areaName AS COUNTRY, r.arrivalDate AS ARRIVAL, rs.statusName AS STATUS FROM Clients c INNER JOIN Requests r ON c.id = r.client_id INNER JOIN Countries co ON r.country_id = co.id INNER JOIN RequestClientEvent rce ON r.id = rce.request_id INNER JOIN RequestStatus rs ON r.status_id = rs.id WHERE r.arrivalDate >= '2020-01-01' -- 核心过滤:同客户没有比当前记录请求日期更晚的记录 AND NOT EXISTS ( SELECT 1 FROM Requests r_check WHERE r_check.client_id = c.id AND r_check.requestDate > r.requestDate ) AND rs.statusName = 'Sold' ORDER BY CLIENT ASC, REQUESTDATE ASC, rs.id ASC LIMIT 10;
注意事项
- 匹配同客户的逻辑必须用Clients表的唯一主键(比如客户ID),不要仅靠客户名称匹配,避免不同客户重名导致的筛选错误
- 规则生效逻辑:只要客户存在晚于某条Sold记录的其他请求,哪怕后续记录的状态不是Sold,这条旧的Sold记录也不会被返回;只有客户最晚的那条请求本身状态为Sold时,才会被纳入结果集
内容的提问来源于stack exchange,提问作者user3292965
相关产品推荐
相关产品推荐

