Thread: please need help: alpha numeric sorting
Hi Gurus,
I need your help for this one:
let's say I have 1 field of type VARCHAR that contains numbers (as ascii) and characters like this:
title
-----------
12.1 cisco ccnp routing
12.2 cisco ccnp remote access
12.11cisco ccnp switching
12.3 cisco ccnp support
I'd like to sort that column in alphanumeric order, like this:
title
-----------
12.1 cisco ccnp routing
12.2 cisco ccnp remote access
12.3 cisco ccnp support
12.11cisco ccnp switching
but if I sort using group by title and order by title asc I have:
title
-----------
12.1 cisco ccnp routing
12.11cisco ccnp switching
12.2 cisco ccnp remote access
12.3 cisco ccnp support
12.11cisco ccnp switching
where "12.11cisco ccnp switching" is before "12.2 cisco ccnp remote access" because it is smaller.
Is it possible ?
thanks for your help
Hello!
The resulting sorting order is quite correct in terms of alphanumeric sorting. If you want numeric sorting, you would probably need to separate the leading number from the tailing string, so you had two fields e.g. "chapter_nr" of type float4 and "chapter_title" of type text (if that's what it is). Then you could just order by chapter_nr and would get a numerically correct sort instead of the alphanumerically correct sort. Alphanumeric always goes character per character from left to right and therefore n.11 is coming before n.2 - the tailing 1 after the first 1 doesn't matter, because n.11 is not regarded as n, point and eleven but n, point and two ones in sequence.
Regards,
Markus
-----Ursprüngliche Nachricht-----
Von: Raouf [mailto:aimeur@prodigy.net]
Gesendet: Freitag, 2. August 2002 10:49
An: pgsql-novice@postgresql.org
Betreff: [NOVICE] please need help: alpha numeric sortingHi Gurus,I need your help for this one:let's say I have 1 field of type VARCHAR that contains numbers (as ascii) and characters like this:title-----------12.1 cisco ccnp routing12.2 cisco ccnp remote access12.11cisco ccnp switching12.3 cisco ccnp supportI'd like to sort that column in alphanumeric order, like this:title-----------12.1 cisco ccnp routing12.2 cisco ccnp remote access12.3 cisco ccnp support12.11cisco ccnp switchingbut if I sort using group by title and order by title asc I have:title-----------12.1 cisco ccnp routing12.11cisco ccnp switching12.2 cisco ccnp remote access12.3 cisco ccnp support12.11cisco ccnp switchingwhere "12.11cisco ccnp switching" is before "12.2 cisco ccnp remote access" because it is smaller.Is it possible ?thanks for your help
is there no way around splitting the field.
i have the same problem, i have ports that i would like to order by numeric. my main problem been that some ports are called a1 - a24 and then b1 - b24 and other devices have ports 1a - 24a, 1b - 24b ect.
-----Original Message-----
From: Markus Wollny [mailto:Markus.Wollny@computec.de]
Sent: Friday, August 02, 2002 10:56 AM
To: Raouf; pgsql-novice@postgresql.org
Subject: Re: [NOVICE] please need help: alpha numeric sortingHello!The resulting sorting order is quite correct in terms of alphanumeric sorting. If you want numeric sorting, you would probably need to separate the leading number from the tailing string, so you had two fields e.g. "chapter_nr" of type float4 and "chapter_title" of type text (if that's what it is). Then you could just order by chapter_nr and would get a numerically correct sort instead of the alphanumerically correct sort. Alphanumeric always goes character per character from left to right and therefore n.11 is coming before n.2 - the tailing 1 after the first 1 doesn't matter, because n.11 is not regarded as n, point and eleven but n, point and two ones in sequence.Regards,Markus-----Ursprüngliche Nachricht-----
Von: Raouf [mailto:aimeur@prodigy.net]
Gesendet: Freitag, 2. August 2002 10:49
An: pgsql-novice@postgresql.org
Betreff: [NOVICE] please need help: alpha numeric sortingHi Gurus,I need your help for this one:let's say I have 1 field of type VARCHAR that contains numbers (as ascii) and characters like this:title-----------12.1 cisco ccnp routing12.2 cisco ccnp remote access12.11cisco ccnp switching12.3 cisco ccnp supportI'd like to sort that column in alphanumeric order, like this:title-----------12.1 cisco ccnp routing12.2 cisco ccnp remote access12.3 cisco ccnp support12.11cisco ccnp switchingbut if I sort using group by title and order by title asc I have:title-----------12.1 cisco ccnp routing12.11cisco ccnp switching12.2 cisco ccnp remote access12.3 cisco ccnp support12.11cisco ccnp switchingwhere "12.11cisco ccnp switching" is before "12.2 cisco ccnp remote access" because it is smaller.Is it possible ?thanks for your help
Hello Markus,
thanks for your reply. Yes I was thinking of splitting my fields in to 2 separate fields but actually I need to have the dot between the numbers, e.g 12.1 or 12.1.2, so actually it won't change anything for me. Do you know if thers's a function that I could use for the sorting ?
thanks,
----- Original Message -----From: Duncan Adams (DNS)Sent: Friday, August 02, 2002 2:00 AMSubject: Re: [NOVICE] please need help: alpha numeric sortingis there no way around splitting the field.i have the same problem, i have ports that i would like to order by numeric. my main problem been that some ports are called a1 - a24 and then b1 - b24 and other devices have ports 1a - 24a, 1b - 24b ect.-----Original Message-----
From: Markus Wollny [mailto:Markus.Wollny@computec.de]
Sent: Friday, August 02, 2002 10:56 AM
To: Raouf; pgsql-novice@postgresql.org
Subject: Re: [NOVICE] please need help: alpha numeric sortingHello!The resulting sorting order is quite correct in terms of alphanumeric sorting. If you want numeric sorting, you would probably need to separate the leading number from the tailing string, so you had two fields e.g. "chapter_nr" of type float4 and "chapter_title" of type text (if that's what it is). Then you could just order by chapter_nr and would get a numerically correct sort instead of the alphanumerically correct sort. Alphanumeric always goes character per character from left to right and therefore n.11 is coming before n.2 - the tailing 1 after the first 1 doesn't matter, because n.11 is not regarded as n, point and eleven but n, point and two ones in sequence.Regards,Markus-----Ursprüngliche Nachricht-----
Von: Raouf [mailto:aimeur@prodigy.net]
Gesendet: Freitag, 2. August 2002 10:49
An: pgsql-novice@postgresql.org
Betreff: [NOVICE] please need help: alpha numeric sortingHi Gurus,I need your help for this one:let's say I have 1 field of type VARCHAR that contains numbers (as ascii) and characters like this:title-----------12.1 cisco ccnp routing12.2 cisco ccnp remote access12.11cisco ccnp switching12.3 cisco ccnp supportI'd like to sort that column in alphanumeric order, like this:title-----------12.1 cisco ccnp routing12.2 cisco ccnp remote access12.3 cisco ccnp support12.11cisco ccnp switchingbut if I sort using group by title and order by title asc I have:title-----------12.1 cisco ccnp routing12.11cisco ccnp switching12.2 cisco ccnp remote access12.3 cisco ccnp support12.11cisco ccnp switchingwhere "12.11cisco ccnp switching" is before "12.2 cisco ccnp remote access" because it is smaller.Is it possible ?thanks for your help
u could try
select <field1> || '.' || <field2> as foo from bar
all though that still leaves me stuck.
-----Original Message-----
From: Raouf [mailto:aimeur@prodigy.net]
Sent: Friday, August 02, 2002 11:26 AM
To: Duncan Adams (DNS); pgsql-novice@postgresql.org
Subject: Re: [NOVICE] please need help: alpha numeric sortingHello Markus,thanks for your reply. Yes I was thinking of splitting my fields in to 2 separate fields but actually I need to have the dot between the numbers, e.g 12.1 or 12.1.2, so actually it won't change anything for me. Do you know if thers's a function that I could use for the sorting ?thanks,----- Original Message -----From: Duncan Adams (DNS)Sent: Friday, August 02, 2002 2:00 AMSubject: Re: [NOVICE] please need help: alpha numeric sortingis there no way around splitting the field.i have the same problem, i have ports that i would like to order by numeric. my main problem been that some ports are called a1 - a24 and then b1 - b24 and other devices have ports 1a - 24a, 1b - 24b ect.-----Original Message-----
From: Markus Wollny [mailto:Markus.Wollny@computec.de]
Sent: Friday, August 02, 2002 10:56 AM
To: Raouf; pgsql-novice@postgresql.org
Subject: Re: [NOVICE] please need help: alpha numeric sortingHello!The resulting sorting order is quite correct in terms of alphanumeric sorting. If you want numeric sorting, you would probably need to separate the leading number from the tailing string, so you had two fields e.g. "chapter_nr" of type float4 and "chapter_title" of type text (if that's what it is). Then you could just order by chapter_nr and would get a numerically correct sort instead of the alphanumerically correct sort. Alphanumeric always goes character per character from left to right and therefore n.11 is coming before n.2 - the tailing 1 after the first 1 doesn't matter, because n.11 is not regarded as n, point and eleven but n, point and two ones in sequence.Regards,Markus-----Ursprüngliche Nachricht-----
Von: Raouf [mailto:aimeur@prodigy.net]
Gesendet: Freitag, 2. August 2002 10:49
An: pgsql-novice@postgresql.org
Betreff: [NOVICE] please need help: alpha numeric sortingHi Gurus,I need your help for this one:let's say I have 1 field of type VARCHAR that contains numbers (as ascii) and characters like this:title-----------12.1 cisco ccnp routing12.2 cisco ccnp remote access12.11cisco ccnp switching12.3 cisco ccnp supportI'd like to sort that column in alphanumeric order, like this:title-----------12.1 cisco ccnp routing12.2 cisco ccnp remote access12.3 cisco ccnp support12.11cisco ccnp switchingbut if I sort using group by title and order by title asc I have:title-----------12.1 cisco ccnp routing12.11cisco ccnp switching12.2 cisco ccnp remote access12.3 cisco ccnp support12.11cisco ccnp switchingwhere "12.11cisco ccnp switching" is before "12.2 cisco ccnp remote access" because it is smaller.Is it possible ?thanks for your help
I don't know of anything - but I'm quite knew to pgsql, too. You might try to do this in your application by parsing the numbers between the dots and the doing a sort.
-----Ursprüngliche Nachricht-----
Von: Raouf [mailto:aimeur@prodigy.net]
Gesendet: Freitag, 2. August 2002 11:26
An: Duncan Adams (DNS); pgsql-novice@postgresql.org
Betreff: Re: [NOVICE] please need help: alpha numeric sortingHello Markus,thanks for your reply. Yes I was thinking of splitting my fields in to 2 separate fields but actually I need to have the dot between the numbers, e.g 12.1 or 12.1.2, so actually it won't change anything for me. Do you know if thers's a function that I could use for the sorting ?thanks,----- Original Message -----From: Duncan Adams (DNS)Sent: Friday, August 02, 2002 2:00 AMSubject: Re: [NOVICE] please need help: alpha numeric sortingis there no way around splitting the field.i have the same problem, i have ports that i would like to order by numeric. my main problem been that some ports are called a1 - a24 and then b1 - b24 and other devices have ports 1a - 24a, 1b - 24b ect.-----Original Message-----
From: Markus Wollny [mailto:Markus.Wollny@computec.de]
Sent: Friday, August 02, 2002 10:56 AM
To: Raouf; pgsql-novice@postgresql.org
Subject: Re: [NOVICE] please need help: alpha numeric sortingHello!The resulting sorting order is quite correct in terms of alphanumeric sorting. If you want numeric sorting, you would probably need to separate the leading number from the tailing string, so you had two fields e.g. "chapter_nr" of type float4 and "chapter_title" of type text (if that's what it is). Then you could just order by chapter_nr and would get a numerically correct sort instead of the alphanumerically correct sort. Alphanumeric always goes character per character from left to right and therefore n.11 is coming before n.2 - the tailing 1 after the first 1 doesn't matter, because n.11 is not regarded as n, point and eleven but n, point and two ones in sequence.Regards,Markus-----Ursprüngliche Nachricht-----
Von: Raouf [mailto:aimeur@prodigy.net]
Gesendet: Freitag, 2. August 2002 10:49
An: pgsql-novice@postgresql.org
Betreff: [NOVICE] please need help: alpha numeric sortingHi Gurus,I need your help for this one:let's say I have 1 field of type VARCHAR that contains numbers (as ascii) and characters like this:title-----------12.1 cisco ccnp routing12.2 cisco ccnp remote access12.11cisco ccnp switching12.3 cisco ccnp supportI'd like to sort that column in alphanumeric order, like this:title-----------12.1 cisco ccnp routing12.2 cisco ccnp remote access12.3 cisco ccnp support12.11cisco ccnp switchingbut if I sort using group by title and order by title asc I have:title-----------12.1 cisco ccnp routing12.11cisco ccnp switching12.2 cisco ccnp remote access12.3 cisco ccnp support12.11cisco ccnp switchingwhere "12.11cisco ccnp switching" is before "12.2 cisco ccnp remote access" because it is smaller.Is it possible ?thanks for your help
--- "Duncan Adams (DNS)" <duncan.adams@vcontractor.co.za> wrote: > u could try > > select <field1> || '.' || <field2> as foo from bar > > all though that still leaves me stuck. -what about select <field1> || '.' || <field2> as foo from bar order by to_number(<field1>,'9999'), to_number(<field2>,'9999'); Assuming that both <field1> and <field2> are alphanumeric characters. This forces numeric sorting by converting <field1> and <field2> to numbers. ludwig. __________________________________________________ Do You Yahoo!? Yahoo! Health - Feel better, live better http://health.yahoo.com
On Fri, 2002-08-02 at 10:00, Duncan Adams (DNS) wrote: > is there no way around splitting the field. > i have the same problem, i have ports that i would like to order by numeric. > my main problem been that some ports are called a1 - a24 and then b1 - b24 > and other devices have ports 1a - 24a, 1b - 24b ect. You don't need to split the field: junk=# select * from f order by t; t ------- 12.1 12.11 12.2 (3 rows) junk=# select * from f order by substr(t,1,strpos(t,'.')-1)::integer, substr(t,strpos(t,'.')+1,999)::integer; t ------- 12.1 12.2 12.11 (3 rows) Oliver Elphick Oliver.Elphick@lfix.co.uk Isle of Wight, UK http://www.lfix.co.uk/oliver GPG: 1024D/3E1D0C1C: CA12 09E0 E8D5 8870 5839 932A 614D 4C34 3E1D 0C1C ======================================== "All scripture is given by inspiration of God, and is profitable for doctrine, for reproof, for correction, for instruction in righteousness;" II Timothy 3:16
Good idea, but (there's always a but unfortunately) the problem is that I can have any number of dots on the t column. t column contains references to paragraphs in books, and the paragraph reference can have any dots like a.b.c.d.e (where a b c d and e are numbers in ascii). t ------- 12.1 12.1.1.1 12.2 12.1.11 12.1.2 12.1.1.1.33.2 I'd like: t ------- 12.1 12.1.1 12.1.1.1.33.2 12.1.2 12.1.11 12.2 thanks all for your help, I really appreciate my users want to see this column sorted this way in there GUI. ----- Original Message ----- From: "Oliver Elphick" <olly@lfix.co.uk> To: "Duncan Adams (DNS)" <duncan.adams@vcontractor.co.za> Cc: <pgsql-novice@postgresql.org> Sent: Friday, August 02, 2002 2:40 AM Subject: Re: [NOVICE] please need help: alpha numeric sorting > On Fri, 2002-08-02 at 10:00, Duncan Adams (DNS) wrote: > > is there no way around splitting the field. > > i have the same problem, i have ports that i would like to order by numeric. > > my main problem been that some ports are called a1 - a24 and then b1 - b24 > > and other devices have ports 1a - 24a, 1b - 24b ect. > > You don't need to split the field: > > junk=# select * from f order by t; > t > ------- > 12.1 > 12.11 > 12.2 > (3 rows) > > junk=# select * from f order by substr(t,1,strpos(t,'.')-1)::integer, > substr(t,strpos(t,'.')+1,999)::integer; > t > ------- > 12.1 > 12.2 > 12.11 > (3 rows) > > Oliver Elphick Oliver.Elphick@lfix.co.uk > Isle of Wight, UK > http://www.lfix.co.uk/oliver > GPG: 1024D/3E1D0C1C: CA12 09E0 E8D5 8870 5839 932A 614D 4C34 3E1D 0C1C > ======================================== > "All scripture is given by inspiration of God, and is > profitable for doctrine, for reproof, for correction, > for instruction in righteousness;" > II Timothy 3:16 > > > ---------------------------(end of broadcast)--------------------------- > TIP 6: Have you searched our list archives? > > http://archives.postgresql.org
On Fri, 2002-08-02 at 09:48, Raouf wrote: > Hi Gurus, > > I need your help for this one: > > let's say I have 1 field of type VARCHAR that contains numbers (as ascii) and characters like this: > > > title > ----------- > 12.1 cisco ccnp routing > 12.2 cisco ccnp remote access > 12.11cisco ccnp switching > 12.3 cisco ccnp support > > > I'd like to sort that column in alphanumeric order, like this: > > title > ----------- > 12.1 cisco ccnp routing > 12.2 cisco ccnp remote access > 12.3 cisco ccnp support > 12.11cisco ccnp switching > > > but if I sort using group by title and order by title asc I have: > > > title > ----------- > 12.1 cisco ccnp routing > 12.11cisco ccnp switching > 12.2 cisco ccnp remote access > 12.3 cisco ccnp support > 12.11cisco ccnp switching > > where "12.11cisco ccnp switching" is before "12.2 cisco ccnp remote access" because it is smaller. > > Is it possible ? > > thanks for your help It is possible (hack at bottom)...but I certainly wouldn't recommend it because as you get more than 10 rows, you'll *really* see a slow down of the function. indexes won't apply, and sorts will be significantly slowed. I'd recommend that you have two more columns 'major' and 'minor', and have these two columns be integers, like this: drop table a; create table a ( major int4, minor int4, description varchar(255) ); Now, when inserting into this table, parse the numbers once using your favorite language, or use a stored function to parse it: insert into a values(12, 1,'12.1 description1'); insert into a values(12, 2,'12.2 description1'); insert into a values(12,10,'12.10description1'); Now, selecting with an appropriate order is a breeze: select description from a order by major, minor; That way you can have indexes on both major and minor, and your sorts will be much faster and far more scalable. For fun, here's the hack that will let you do thwat you wanted in the first place...(blech!) HACK FOLLOWS ------------ -- First, create a test bed: drop table a; create table a (b varchar(255)); insert into a values ('12.1 testing'); insert into a values ('12.2 testing'); insert into a values ('12.10testing'); -- Now, see if we still have this problem... select * from a order by b; -- Okay, now convert the leading number (12.1) into '12.001', so -- we can then sort numerically, and do so. Yuck. select * from a order by -- break out the digits before the '.' substring( substring(b for 5) for position('.' in substring(b for 5))-1) -- add the '.' back ||'.'|| -- Turn that back to a string to_char( -- Turn them to a zero padded number. to_number( -- Get the digits after the '.' substring( substring(b for 5) from position('.' in substring(b for 5))+1) ,'999') ,'FM000'); -Ken