如何编写SQL查询获取每位客户Lawn Mowing服务的最新更新状态?
获取客户Lawn Mowing服务的最新状态
我们的目标是从服务更新记录表中,筛选出每位客户针对Lawn Mowing服务的最后一次操作(添加/移除),以此作为该服务的当前状态。
原表结构与数据
| id | 客户 | 服务 | 移除/添加 | update_date |
|---|---|---|---|---|
| 1 | John Smith | Lawn Mowing | 移除 | 3-1-23 |
| 2 | John Smith | Lawn Mowing | 添加 | 6-1-22 |
| 3 | John Smith | Fertilizing | 添加 | 6-1-22 |
| 4 | Jane Doe | Lawn Mowing | 添加 | 7-15-23 |
| 5 | Alex Reynolds | Lawn Watering | 添加 | 6-18-23 |
| 6 | Alex Reynolds | Lawn Mowing | 添加 | 6-18-23 |
解决方案1:使用窗口函数(推荐)
窗口函数可以高效对每个客户的Lawn Mowing记录排序,直接提取最新的一条记录。以下是适配MySQL 8+/PostgreSQL/SQL Server等现代数据库的通用写法:
SELECT 客户, 服务, `移除/添加` AS 当前状态, update_date AS 最后更新时间 FROM ( SELECT *, ROW_NUMBER() OVER ( PARTITION BY 客户 ORDER BY STR_TO_DATE(update_date, '%m-%d-%y') DESC ) AS rn FROM 服务更新记录表 WHERE 服务 = 'Lawn Mowing' ) t WHERE rn = 1;
代码说明:
- 内层查询:先筛选所有
服务 = 'Lawn Mowing'的记录,再用ROW_NUMBER()按客户分组,每组内将记录按update_date(转成日期类型后)降序排序,给每条记录分配行号rn(最新记录的行号为1)。 - 外层查询:仅保留行号
rn = 1的记录,即为每个客户该服务的最新状态。
解决方案2:子查询关联(兼容旧版数据库)
如果你的数据库不支持窗口函数(如MySQL 5.x),可以先通过子查询获取每个客户Lawn Mowing服务的最新更新日期,再关联原表提取对应记录:
SELECT t1.客户, t1.服务, t1.`移除/添加` AS 当前状态, t1.update_date AS 最后更新时间 FROM 服务更新记录表 t1 JOIN ( SELECT 客户, MAX(STR_TO_DATE(update_date, '%m-%d-%y')) AS latest_date FROM 服务更新记录表 WHERE 服务 = 'Lawn Mowing' GROUP BY 客户 ) t2 ON t1.客户 = t2.客户 AND STR_TO_DATE(t1.update_date, '%m-%d-%y') = t2.latest_date AND t1.服务 = 'Lawn Mowing';
查询结果
执行任意一种查询后,会得到如下结果:
| 客户 | 服务 | 当前状态 | 最后更新时间 |
|---|---|---|---|
| John Smith | Lawn Mowing | 移除 | 3-1-23 |
| Jane Doe | Lawn Mowing | 添加 | 7-15-23 |
| Alex Reynolds | Lawn Mowing | 添加 | 6-18-23 |
注意事项
- 若需要包含从未办理过Lawn Mowing服务的客户(可显示“无服务记录”),可以左连接单独的客户表(如果存在),结合
COALESCE函数处理空值。 - 必须将
update_date转为日期类型后再排序,避免字符串排序导致的逻辑错误(例如字符串排序时'10-1-23'会被判定为小于'3-1-23')。
内容的提问来源于stack exchange,提问作者David Reke
相关产品推荐
相关产品推荐

