V2EX = way to explore
V2EX 是一个关于分享和探索的地方
Sign Up Now
For Existing Member  Sign In
• 请不要在回答技术问题时复制粘贴 AI 生成的内容
simonlu9
V2EX  ›  程序员

mysql 怎么保证每次查出来的排名是一致的

  •  
  •   simonlu9 · Sep 6, 2022 · 3181 views
    This topic created in 1340 days ago, the information mentioned may be changed or developed.

    项目有个需求要获取用户销售额的排名,于是在 mysql 实现,但是当销售额都等于 0 的时候,排序是很不稳定的,每次获取都不一样,有什么好的解决方法呢

    SELECT
    	pos AS sort,
    	amount,
    	user_id AS userId
    FROM
    	(
    		SELECT
    			rank.*,@rank :=@rank + 1 AS pos
    		FROM
    			(
    				SELECT
    					user_id,
    					sale_amount amount
    				FROM
    					store
    				UNION
    					SELECT
    						user_id,
    						amount
    					FROM
    						store_rank
    					ORDER BY
    						amount DESC
    			) rank,
    			(SELECT @rank := 0) B
    	) c
    WHERE
    	user_id = 1015228275321995264 ;
    
    19 replies    2022-09-07 17:45:23 +08:00
    ranleng
        1
    ranleng  
       Sep 6, 2022   ❤️ 2
    再以名字或者 user_id 排...
    chendy
        2
    chendy  
       Sep 6, 2022   ❤️ 4
    加一个创建时间之类的排序做默认顺序
    HHHHHQ
        3
    HHHHHQ  
       Sep 6, 2022
    楼上两位正解。
    wxf666
        4
    wxf666  
       Sep 6, 2022
    销售额都等于 0 时,排名不应该是一样的嘛。。

    不考虑使用连 SQLite 都支持的窗口函数 rank() OVER(...) 嘛?
    simonlu9
        5
    simonlu9  
    OP
       Sep 6, 2022
    @wxf666 当系统有多个都为 0 的数据就每次都不一样啦
    wxf666
        6
    wxf666  
       Sep 6, 2022
    @simonlu9 啥意思。。

    1. 你希望销售额相同的用户,他们的排名相同吗?

    2. 你的 SQL 最里层的『 SELECT ... UNION SELECT ... ORDER BY ...』,每次获取,结果都一样吗?
    simonlu9
        7
    simonlu9  
    OP
       Sep 6, 2022
    @wxf666 相同金额不获取的排名是不一样的,所以导致每次用户获取自己的排名不一样,所以单个字段排序是解决不了这个问题,第二个就是每次返回的结果都不一样
    wxf666
        8
    wxf666  
       Sep 6, 2022
    @simonlu9 还是没看懂。。举些例子吧,你希望是这样排名吗?

    用户 ID  销售额 排名
    ———————————
     1  100  1
     2  100  1
     3    0  3
     4    0  3
     5    0  3
    frank1256
        9
    frank1256  
       Sep 6, 2022
    order by amount desc, id desc
    eason1874
        10
    eason1874  
       Sep 6, 2022
    排序条件写两个就行了,比如其他人说的,加上 id 排序
    wineast
        11
    wineast  
       Sep 6, 2022
    加一个第二排序即可,比如 id ,创建时间 etc
    simonlu9
        12
    simonlu9  
    OP
       Sep 6, 2022
    @wxf666 谢谢你的热心回复了,我希望相同金额的用户排名是不一样的吗,
    就是比如有系统有 100 个人销售额是 0 的,那我的排名是多少呢,现在要保证每个用户的排名都是不一样的,
    上面的语句就每次返回的排名都不一样,很不稳定,所以相同销售额的排名不稳定,要额外加多一个字段,这种问题在延伸就会导致分页会出现重复的数据
    ktqFDx9m2Bvfq3y4
        13
    ktqFDx9m2Bvfq3y4  
       Sep 6, 2022
    加个排名字段定期更新?我之前就是这么干的,每小时更新排名。
    zhuweiyou
        14
    zhuweiyou  
       Sep 6, 2022
    相同的销售额, 排名应该相同才对, 参考 8 楼的图表.

    mysql 8 有排名函数.
    xiangyuecn
        15
    xiangyuecn  
       Sep 6, 2022
    相同值的本身就是乱序,谁排前面看心情。

    常规的是根据人名排序,这就是命,看投胎。
    wxf666
        16
    wxf666  
       Sep 6, 2022
    @simonlu9 感觉和前几楼说的那样,在 ORDER BY 里加个 user_id 之类的字段就好
    Xusually
        17
    Xusually  
       Sep 6, 2022 via iPhone
    简单的办法就是再加入一个不重复的排序,比如主键,user id 之类的
    dobelee
        18
    dobelee  
       Sep 6, 2022
    这是产品需求不明确,一般这种全量排行榜会是多维的,会加上注册时间、活跃时间、ID 等二重排序来避免等分乱序。
    fiveStarLaoliang
        19
    fiveStarLaoliang  
       Sep 7, 2022
    不要让它自己排序,手动加入排序规则,否则开发一时爽,维护火葬场
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Solana   ·   5893 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 59ms · UTC 03:05 · PVG 11:05 · LAX 20:05 · JFK 23:05
    ♥ Do have faith in what you're doing.