Reputation: 79
Using postgresql on a mac, I'm trying to order names in descending but I have noticed if the two names have the same first letter it does not check the second letter when trying to order.
For example suppose you have the following strings:
Amen, Alia, Atis,...etc
They should ideally be order as:
Alia, Amen, Atis,..etc
But postgresql only checks the first letter and doesn't seem to check the entire string. Therefore the order of names returned by postgresql is:
Atis, Alia, Amen,..etc
or in just some random order. I have set the database collation to en_us.utf8.
The simplified query I'm trying to use is:
SELECT name
FROM properties
ORDER BY name;
How can I make postgresql order by the entire string, is that possible?
Update: When I try the query in pgadmin III, I find that it produces the same results, I think it may have something to do with the configuration of postgreSQL.
My configs of db are: collation and character type are: en_CA.UTF-8 tablespace: pg_default
Is there something wrong with the configuration I have set up on a mac?
Upvotes: 1
Views: 2896
Reputation: 2243
My guess is you are experiencing issues with collation and/or non-printable characters.
You can try different collations as per http://www.postgresql.org/docs/9.1/static/collation.html with:
SELECT name COLLATE "C", name::bytea FROM properties
LEFT OUTER JOIN observations on properties.id =observations.id order by 1 desc;
and you will be able to both experiment with collation (1st col) and see what exactly (hex binary value) is stored in name
(2nd col).
Edit: After finding this Postgres.app issue, I'm fairly confident you've hit a bug in OSX collation support. To confirm, you can try sorting the same text in console using sort
.
I don't know if a workaround exists at this moment, but the PGDG is aware of the problem and if all goes well, PostgreSQL 9.6 might solve your problem.
Upvotes: 2
Reputation: 10680
Natural order sort
it's what You looking for.
CREATE FUNCTION btrsort_nextunit(text) RETURNS text AS $$
SELECT CASE WHEN $1 ~ '[^0-9]+' THEN
COALESCE( SUBSTR( $1, LENGTH(SUBSTRING($1 FROM '[^0-9]+'))+1 ),
'' )
ELSE
COALESCE( SUBSTR( $1, LENGTH(SUBSTRING($1 FROM '[0-9]+'))+1 ),
'' )
END
$$ LANGUAGE SQL;
CREATE FUNCTION btrsort(text, integer) RETURNS text AS $$
SELECT CASE WHEN $2-1>0
THEN
RPAD(SUBSTR(COALESCE(SUBSTRING($1 FROM '^[^0-9]+'), ''), 1, 12), 12, ' ') ||
LPAD(SUBSTR(COALESCE(SUBSTRING(btrsort_nextunit($1) FROM '^[0-9]+'), ''), 1, 12), 12, 0) || btrsort(btrsort_nextunit(btrsort_nextunit($1)), $2-1)
ELSE
RPAD(SUBSTR(COALESCE(SUBSTRING($1 FROM '^[^0-9]+'), ''), 1, 12), 12, ' ') ||
LPAD(SUBSTR(COALESCE(SUBSTRING(btrsort_nextunit($1) FROM '^[0-9]+'), ''), 1, 12), 12, 0)
END
;
$$ LANGUAGE SQL;
CREATE FUNCTION btrsort(text) RETURNS text AS $$
SELECT btrsort($1, 10);
$$ LANGUAGE SQL;
SELECT room_number
FROM (SELECT room_number, btrsort(room_number) AS room_sort
FROM rooms
ORDER BY room_sort) AS foo
room_number
-----------
8
9
9a
10
http://www.postgresql.org/docs/8.0/interactive/queries-order.html http://2kan.tumblr.com/post/361326656/postgres-natural-ordering
Upvotes: 0