You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

多对多关联场景下SQL查询如何避免返回重复记录

JOIN结果行数异常排查与优化方案

核心原因

结果行数远大于事故表原始行数的核心原因是Rentals表中同一个关联键(customer_id/姓名)存在多条记录,1条事故表数据会匹配到同一个客户的N条租赁记录,最终总数据量被放大到1500的数十倍。

排查步骤

  • 先确认Rentals表的重复情况,执行查询:
    SELECT customer_id, COUNT(*) AS rental_count FROM rentals GROUP BY customer_id HAVING COUNT(*) > 1 ORDER BY rental_count DESC
    返回结果中的条目就是存在多条租赁记录的客户,可直接验证行数放大的原因。
  • 明确业务关联逻辑:你需要的是事故发生时对应的那条租赁记录?还是客户的最新静态属性?还是该客户所有租赁记录的关联结果?不同需求对应完全不同的关联写法。

通用优化方案

场景1:仅需要客户静态属性(出生日期、是否封禁等不随租赁单变化的字段)

先对Rentals表按关联键去重后再关联,避免多匹配:

SELECT a.*,
r.market,
r.date_of_birth,
r.is_blocked,
r.rate_type
FROM `accidents` a
LEFT JOIN (
    SELECT DISTINCT customer_id, market, date_of_birth, is_blocked, rate_type 
    FROM `rentals`
) r
USING (customer_id)
ORDER BY accident_dt DESC

场景2:需要关联事故发生时对应的租赁记录

补充时间匹配条件,限定仅匹配事故发生时段内的租赁单:

SELECT a.*,
r.market,
r.date_of_birth,
r.is_blocked,
r.rate_type
FROM `accidents` a
LEFT JOIN `rentals` r
ON a.customer_id = r.customer_id
-- 请根据实际表字段调整时间范围判断逻辑
AND a.accident_dt BETWEEN r.rental_start_dt AND r.rental_end_dt
ORDER BY accident_dt DESC

场景3:仅需要客户最新一条租赁记录的属性

用窗口函数提前过滤出每个客户的最新租赁记录再关联:

SELECT a.*,
r.market,
r.date_of_birth,
r.is_blocked,
r.rate_type
FROM `accidents` a
LEFT JOIN (
    SELECT *,
    ROW_NUMBER() OVER(PARTITION BY customer_id ORDER BY rental_create_dt DESC) AS rn
    FROM `rentals`
) r
ON a.customer_id = r.customer_id AND r.rn = 1
ORDER BY accident_dt DESC

内容的提问来源于stack exchange,提问作者lillemongrab

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.09 10:36:03