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

MySQL分组筛选:排除每组最高cash的重复token行(禁用EXCEPT/OFFSET)

解决方案

这问题我之前在低版本MySQL环境里也碰到过,既然没法用EXCEPT和OFFSET,咱们可以换个思路:先定位每个重复token组里的最高cash值,然后过滤掉等于这个最大值的行,同时保证只处理有重复的token。下面给你两种实用的方案:

方法一:关联子查询实现

直接在WHERE子句里添加条件,筛选出当前行cash小于对应token组最大cash的记录,同时保留token重复的前提:

SELECT tu.id, tu.token, tu.cash
FROM users tu
WHERE (SELECT COUNT(*) FROM users WHERE token = tu.token) > 1
  AND tu.cash < (SELECT MAX(cash) FROM users WHERE token = tu.token)
ORDER BY tu.token, tu.cash DESC;

逻辑说明

  • 第一个子查询(SELECT COUNT(*) FROM users WHERE token = tu.token) > 1:确保只处理存在重复的token组,和你原语句的逻辑一致;
  • 第二个子查询tu.cash < (SELECT MAX(cash) FROM users WHERE token = tu.token):排除掉当前token组里cash最高的那一行,剩下的就是每组中除首行外的其他重复行;
  • 最后保持你原有的排序规则,按token、cash降序排列。

方法二:GROUP BY + JOIN(性能更优)

如果数据量较大,用GROUP BY先预计算每个重复token的最大cash值,再通过JOIN关联过滤,性能会比关联子查询更好:

SELECT tu.id, tu.token, tu.cash
FROM users tu
JOIN (
    -- 先找出所有有重复的token,以及对应的最大cash值
    SELECT token, MAX(cash) AS max_cash
    FROM users
    GROUP BY token
    HAVING COUNT(*) > 1
) tm ON tu.token = tm.token AND tu.cash < tm.max_cash
ORDER BY tu.token, tu.cash DESC;

逻辑说明

  • 子查询里先按token分组,用HAVING COUNT(*) > 1筛选出有重复的token,同时计算每组的最大cash;
  • 原表和这个子查询通过token关联,并且只保留tu.cash < tm.max_cash的行,这样就精准排除了每组中cash最高的记录;
  • 同样保持原有的排序规则,结果和方法一一致,但子查询只执行一次,大数据量下效率更高。

你可以根据自己的数据集大小选择合适的方案,两种都能满足你的需求,而且完全避开了EXCEPT和OFFSET的限制。

内容的提问来源于stack exchange,提问作者Виктор К.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.13 06:36:42