如何对以数字开头的标题正确排序,解决分级编号排序错位问题
问题根因
默认的字符串字典序排序是逐字符比对ASCII码值,层级编号会被当成普通字符串处理,和人工对编号的语义排序逻辑不符,才会出现排序错位的问题。
解决方法
方案1:数据库层面排序(推荐,适配大数据量场景)
根据你使用的数据库调整order逻辑,将开头的编号转换为可按层级排序的格式:
- PostgreSQL 环境
用string_to_array把编号拆分为整数数组排序,天然支持任意层级的编号:titles.where(status: 1) .order(Arel.sql("string_to_array(split_part(name, ' ', 1), '.')::int[] ASC, name ASC")) - MySQL 环境
逐层提取编号段转为数值排序,可根据业务的最大编号层级调整提取段数:titles.where(status: 1) .order(Arel.sql(<<~SQL.squish)) CAST(SUBSTRING_INDEX(SUBSTRING_INDEX(name, '.', 1), ' ', 1) AS UNSIGNED) ASC, CAST(SUBSTRING_INDEX(SUBSTRING_INDEX(name, '.', 2), '.', -1) AS UNSIGNED) ASC, CAST(SUBSTRING_INDEX(SUBSTRING_INDEX(name, '.', 3), '.', -1) AS UNSIGNED) ASC, name ASC SQL
方案2:Ruby 内存排序(适配千条以内的小数据量场景)
数据量不大的情况下可以直接在应用层排序,自动适配任意层级的编号,不需要修改数据库查询逻辑:
titles.where(status: 1).sort_by do |item| num_segment = item.name.split.first num_segment.split('.').map(&:to_i) end
内容的提问来源于stack exchange,提问作者Nicolás
相关产品推荐
相关产品推荐

