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

MySQL按指定列查询重复记录并获取no_purchase最高对应行的方法

问题原因

你之前的写法存在逻辑漏洞,MySQL 5.7及以上版本默认开启ONLY_FULL_GROUP_BY校验规则,直接在分组查询中返回非分组、非聚合的字段(比如你示例里的no_purchase),返回的结果是随机匹配的,无法保证和你取的MAX(id)/MAX(no_purchase)属于同一条记录,这就是你拿不到正确关联ID的核心原因。

解决方案1:MySQL 8.0+ 窗口函数方案(推荐)

用ROW_NUMBER()窗口函数给同分组下的记录按no_purchase降序排序,直接取排序第一的记录即可,同时支持筛选有重复的分组:

SELECT id, name, address, no_purchase, cnt
FROM (
    SELECT 
        id, name, address, no_purchase,
        COUNT(*) OVER (PARTITION BY name, address) AS cnt,
        ROW_NUMBER() OVER (PARTITION BY name, address ORDER BY no_purchase DESC, id DESC) AS rn
    FROM list
) t
WHERE rn = 1 AND cnt > 1;

说明:如果同一个name+address分组下存在多条相同最大no_purchase的记录,ORDER BY后面加id DESC会取ID最大的那条,加id ASC会取ID最小的那条,可按需调整。

解决方案2:兼容MySQL 5.x 关联子查询方案

先分组拿到每个name+address对应的最大no_purchase,再关联回原表匹配完整记录:

SELECT l.id, l.name, l.address, l.no_purchase, t.cnt
FROM list l
INNER JOIN (
    SELECT name, address, MAX(no_purchase) AS max_purchase, COUNT(id) AS cnt
    FROM list
    GROUP BY name, address
    HAVING cnt > 1
) t ON l.name = t.name AND l.address = t.address AND l.no_purchase = t.max_purchase;

说明:如果同分组下有多个相同最大no_purchase的记录,这个查询会把所有符合条件的都返回,如需只取一条,可在外层再加GROUP BY l.name, l.address,按你需要的ID规则加MAX(id)/MIN(id)聚合即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 09:45:02