带有包含数字和文本的 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"
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"