MySQL中ROW_NUMBER() 查询数据去重,并排序

在正常的业务需求中常见的就是IP去重,倒序展示用户最新的10条数据。
例如:
user_login_info 表中有 id(主键、自增),ip,user_id 等字段。
此时需要通过通过IP去重,然后id倒叙。

想到用distinct 来实现去重:

select distinct ip from user_login_info where user_id = 1  order by id desc limit 10;


此时报错提示 排序的id字段不在查询列表中,无法进行排序。
如果放到查询语句中,则去重将无效。

之后又想到用子查询的方式:
 

select distinct ip from(
 select ip,id from user_login_info where user_id = 1  order by id desc;
) tab limit 10

此方式是可以实现去重,但是倒序无效了。
之后考虑不使用 distinct 而选择使用的 Group By。

SELECT ip FROM user_login_info 
      where user_id = 1
         GROUP BY ip
         ORDER BY MIN(id) desc limit 10;

ORDER BY MIN(id) 表示按照每组中id的最小值进行排序,也就是通过取每组最小的id值对应的记录顺序来对去重后的 IP 进行排序,当然你也可以使用MAX(id)等其他聚合函数来决定排序依据,不过一般来说按照最小id排序能保证相对原始顺序更靠前的记录优先展示。同样,如果希望降序排序,可写成ORDER BY MIN(id) DESC。

但是实现起来还是有问题。
最后选择使用 ROW_NUMBER() 函数给每行记录添加行号:

SELECT sign, location
FROM (
    SELECT sign, location,
           ROW_NUMBER() OVER (PARTITION BY sign ORDER BY check_time DESC) AS row_num
    -- 按照sign分区,在每个分区内(即针对sign)按验证时间倒序排序,并赋予行号
    FROM game_account_check_record
    WHERE sign = '***'  -- 按照唯一标识
) AS subquery
WHERE row_num <= 2
-- 只取行号小于等于2的记录,也就是该指定用户最新的2条验证记录
ORDER BY row_num;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值