My PostgreSQL sorts the way you want. The way PostgreSQL compares strings is determined by locale and collation. When you create database using createdb
there is -l
option to set locale. Also you can check how it is configured in your environment using psql -l
:
[postgres@test]$ psql -l
List of databases
Name | Owner | Encoding | Collate | Ctype | Access privileges
---------+----------+----------+------------+------------+-----------------------
mn_test | postgres | UTF8 | pl_PL.UTF8 | pl_PL.UTF8 |
As you see my database uses Polish collation.
If you created database using other collation then you can use other collation in query just like:
SELECT * FROM sort_test ORDER BY name COLLATE "C";
SELECT * FROM sort_test ORDER BY name COLLATE "default";
SELECT * FROM sort_test ORDER BY name COLLATE "pl_PL";
You can list available collations by:
SELECT * FROM pg_collation;
EDITED:
Oh, I missed that 'a11' must be before 'a2'.
I don't think standard collation can solve alphanumeric sorting. For such sorting you will have to split string into parts just like in Clodoaldo Neto response. Another option that is useful if you frequently have to order this way is to separate name field into two columns. You can create trigger on INSERT and UPDATE that split name
into name_1
and name_2
and then:
SELECT name FROM sort_test ORDER BY name_1 COLLATE "en_EN", name_2;
(I changed collation from Polish into English, you should use your native collation to sort letters like a?c? etc)
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…