MySQL如何将空字符串排在末尾且不按字母序排序
MySQL:将空字符串排在结果集末尾且保留非空记录原始顺序
问题场景
原始数据:
comment -------------------------- Apple '' Orange Avocado Banana Cauliflower Broccoli '' Potato Cabbage
期望结果(非空记录保留原始顺序,空字符串排最后):
comment -------------------------- Apple Orange Avocado Banana Cauliflower Broccoli Potato Cabbage '' ''
实际执行现有查询后,非空记录按字母序排序,不符合需求:
comment -------------------------- Apple Avocado Banana Broccoli Cauliflower Cabbage Orange Potato '' ''
你尝试过的查询:
SELECT * FROM `comments` order by NULLIF(NULLIF(comment ,'0'),''),comment desc; SELECT * FROM `comments` ORDER BY IF(comment IS NULL, 1,0), comment desc; SELECT * FROM `comments` ORDER BY case when comment is null then 1 else 0 end, comment desc
问题原因
你之前的查询在排序时都额外指定了comment相关的排序规则(比如comment desc),这会强制非空记录按字母顺序排列,覆盖了原始的记录顺序。要保留原始顺序,需要基于记录的插入顺序标识来排序,而非字段内容。
解决方案
方案1:表有自增主键(如id)
如果表存在自增主键(通常用来标识插入顺序),直接用主键排序:
SELECT * FROM `comments` ORDER BY (comment = '') ASC, id ASC;
(comment = '') ASC:将空字符串标记为1,非空为0,升序排序后空字符串会排在最后id ASC:保留非空记录的原始插入顺序
方案2:无主键且MySQL版本≥8.0
用窗口函数ROW_NUMBER()生成原始顺序的行号,再基于行号排序:
SELECT comment FROM ( SELECT comment, ROW_NUMBER() OVER () AS row_num FROM `comments` ) AS temp ORDER BY (comment = '') ASC, row_num ASC;
ROW_NUMBER() OVER ()会按数据读取的原始顺序生成行号- 外层排序先区分空与非空,再按行号保留原始顺序
方案3:MyISAM引擎特殊处理
如果是MyISAM引擎,可以用内置的_rowid字段(对应物理存储顺序):
SELECT * FROM `comments` ORDER BY (comment = '') ASC, _rowid ASC;
内容的提问来源于stack exchange,提问作者Ahmadz Issa
相关产品推荐
相关产品推荐

