带有包含数字和文本的 varchar 字段的 order 子句

order clause with varchar field containing numbers and text

sql:

create table users(username varchar(256));

insert into users values ('1112');
insert into users values ('126');
insert into users values ('124');
insert into users values ('cats');

select * from users order by username;

结果顺序:1112, 124, 126, cats

有没有办法让 order 子句成为 'alphabetical, but numerical if a number',即:124, 126, 1112,cats

我试过了:

select * from users order by ('000'::varchar || username)

但这无济于事

一些丑陋的 hack 来得很快:

t=# select * from users 
order by ascii(username), regexp_replace(username,'[a-z]','0','g')::bigint, username;
                    username
------------------------------------------------
 124
 126
 1112
 cats
(4 rows)

认为

  • 数字的ascii码在字母之前是升序的
  • regexp_replace 将对数字进行排序,而不是数字
  • 最后按字母顺序排列
select *
from users 
order by
  case
    when username ~ '^[0-9]+$' then username::bigint
    else null
  end,
  username;

数据:

insert into users values ('1112');
insert into users values ('126');
insert into users values ('124');
insert into users values ('22');
insert into users values ('cats');

给出:

"22"
"124"
"126"
"1112"
"cats"