SQL租车系统:查询曾租天窗车辆客户的最后租车信息求助
解决方案:获取指定客户的最后一次租车车辆信息
原查询的核心问题
EXISTS子句未关联主查询的car a表,逻辑完全脱节,无法筛选目标车辆GROUP BY ak.date分组逻辑错误,按日期分组无法定位每个客户的最后一次租车记录- 表连接关系混乱,
car a2直接关联customer不符合常规租车系统表结构(应为租车单关联客户,再关联车辆)
正确实现思路
分三步完成需求:
- 筛选所有租过带天窗(
option_id=2)车辆的客户ID - 找出这些客户的最后一次租车记录(取最大租车日期对应的租车单)
- 通过租车单关联对应车辆,获取车辆信息
基于窗口函数的高效实现
假设表结构符合常规租车系统设计:
customer:customer_id(客户主键)rent:rent_id(租车单主键)、customer_id(关联客户)、rent_date(租车日期)car_rent:rent_id(关联租车单)、car_id(关联车辆)car:car_id(车辆主键)、package_id(关联套餐)、rent_sell(车辆状态,1表示可租/已租)package_package_option:package_id(关联套餐)、option_id(关联配置项)
对应的SQL语句:
WITH qualified_customers AS ( -- 第一步:筛选租过带天窗车辆的客户 SELECT DISTINCT m.customer_id FROM customer m JOIN rent k ON m.customer_id = k.customer_id JOIN car_rent ak ON k.rent_id = ak.rent_id JOIN car a2 ON ak.car_id = a2.car_id JOIN package_package_option pk ON a2.package_id = pk.package_id WHERE pk.option_id = 2 ), customer_last_rent AS ( -- 第二步:获取每个符合条件客户的最后一次租车记录 SELECT k.customer_id, k.rent_id, ROW_NUMBER() OVER (PARTITION BY k.customer_id ORDER BY k.rent_date DESC) AS rn FROM rent k JOIN qualified_customers qc ON k.customer_id = qc.customer_id ) -- 第三步:关联获取车辆信息 SELECT a.* FROM car a JOIN car_rent ak ON a.car_id = ak.car_id JOIN customer_last_rent clr ON ak.rent_id = clr.rent_id WHERE clr.rn = 1 AND a.rent_sell = 1;
无窗口函数的替代实现
若你的SQL版本不支持窗口函数,可使用子查询获取客户最大租车日期:
WITH qualified_customers AS ( SELECT DISTINCT m.customer_id FROM customer m JOIN rent k ON m.customer_id = k.customer_id JOIN car_rent ak ON k.rent_id = ak.rent_id JOIN car a2 ON ak.car_id = a2.car_id JOIN package_package_option pk ON a2.package_id = pk.package_id WHERE pk.option_id = 2 ), customer_max_rent_date AS ( -- 获取每个客户的最后租车日期 SELECT customer_id, MAX(rent_date) AS last_rent_date FROM rent WHERE customer_id IN (SELECT customer_id FROM qualified_customers) GROUP BY customer_id ) -- 关联获取车辆信息 SELECT a.* FROM car a JOIN car_rent ak ON a.car_id = ak.car_id JOIN rent k ON ak.rent_id = k.rent_id JOIN customer_max_rent_date cmrd ON k.customer_id = cmrd.customer_id AND k.rent_date = cmrd.last_rent_date WHERE a.rent_sell = 1;
性能优化建议
- 为以下字段创建索引:
rent(customer_id, rent_date)car_rent(rent_id, car_id)package_package_option(package_id, option_id)car(car_id, package_id, rent_sell)
- 避免使用
SELECT *,仅查询所需字段,减少数据传输 - 定期清理无效数据,避免查询扫描过多冗余记录
内容的提问来源于stack exchange,提问作者Ömer Gün
相关产品推荐
相关产品推荐

