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

SQL关联mobile_payments表后action_id重复,Group By、DISTINCT无效如何解决?

问题原因分析

你遇到的重复数据问题是因为customer.mobile_payments表和customer.actions表是一对多关系:同一个customer_id在mobile_payments表中存在多条支付记录,关联后每条action记录会和该客户的所有支付记录做笛卡尔积拼接,所以原本500条的action数据会膨胀到4000条。
之前用DISTINCT或者GROUP BY无效,是因为同一个action_id关联的多条支付记录的payment_type值不同,聚合时无法自动合并。

解决方案

以下方案均可以实现每个action_id仅返回一条结果,同时保留所有满足过滤条件的actions记录:

方案1:窗口函数取单条支付记录(支持MySQL8.0+、PostgreSQL、SQL Server等主流数据库)

如果需要按业务规则取每个客户的某一条支付记录(比如最新的支付记录对应的payment_type),可以先对mobile_payments表按customer_id分组排序,每个组仅取第一条后再关联:

select a.action_id, a.customer_id, a.request_date, mp.payment_type 
from customer.actions a
inner join customer.customers c on c.id = a.customer_id
inner join customer.entities e on e.id = c.entity_id
-- 预处理支付表,每个customer_id只取1条记录
left join (
    select 
        customer_id, 
        payment_type,
        -- 按支付时间倒序取最新的一条,无支付时间字段可以替换为其他排序规则,无需规则随便取可以写order by 1
        row_number() over(partition by customer_id order by payment_time desc) as rn 
    from customer.mobile_payments
) mp on mp.customer_id = a.customer_id and mp.rn = 1
where a.request_url like '%/test%'
order by a.request_date desc;

注意:这里用left join是为了保留没有支付记录的action数据,如果仅需要返回有支付记录的action,可以把left join改回inner join。


方案2:老版本MySQL兼容方案(不支持窗口函数的场景)

如果使用MySQL5.x及以下不支持窗口函数的版本,可以先对支付表按customer_id做聚合,每个客户仅取一个payment_type:

select a.action_id, a.customer_id, a.request_date, mp.payment_type 
from customer.actions a
inner join customer.customers c on c.id = a.customer_id
inner join customer.entities e on e.id = c.entity_id
left join (
    select customer_id, max(payment_type) as payment_type -- 无需规则随便取可以用max/min,要取最新的可以关联max(payment_time)过滤对应记录
    from customer.mobile_payments
    group by customer_id
) mp on mp.customer_id = a.customer_id
where a.request_url like '%/test%'
order by a.request_date desc;

方案3:子查询直接取值(简单场景最便捷)

如果仅需要获取payment_type一个字段,可以直接在select子句中写子查询取值:

select 
    a.action_id, 
    a.customer_id, 
    a.request_date,
    (select payment_type from customer.mobile_payments where customer_id = a.customer_id limit 1) as payment_type
from customer.actions a
inner join customer.customers c on c.id = a.customer_id
inner join customer.entities e on e.id = c.entity_id
where a.request_url like '%/test%'
order by a.request_date desc;

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

相关产品推荐
方舟 Agent Plan

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

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