Reputation: 3
I have a scenario where a field contains both character and number, I am suppose to sort it as given below.
City 1
City 2
City 3
City 4a
City 4b
City 4c
City 10
City 11a
City 11b
Town 1
Town 2
Town 3a
Town 4b
Town 10
The query should also take into account that in future more fields can be added like 100
, 101a
, etc.
Thanks in advance.
Upvotes: 0
Views: 43
Reputation: 36107
Another possible approach is using regular expressions.
Here is an example how to parse a string and divide in into subfields:
select col,
regexp_replace( col, '\D+\s+(\d+).*','\1') As field1,
regexp_replace( col, '\D+\s+\d+(\D*),*.*','\1') As field2,
regexp_replace( col, '\D+\s+\d+\D*,*(\d*)','\1') As field3
from table1
ORDER BY field1, field2, field3
;
If only a sort is required, then use these functions in ORDER BY clause:
select * from table1
order by
regexp_replace( col, '\D+\s+(\d+).*','\1'),
regexp_replace( col, '\D+\s+\d+(\D*),*.*','\1'),
regexp_replace( col, '\D+\s+\d+\D*,*(\d*)','\1')
Demo: http://sqlfiddle.com/#!4/8f289/4
But for large dataset this will be horrible slow.
You need to normalize data in the table - parse it during insertion and store each field in separate column in the table, then create an index on these columns.
A sort using a cast to numeric:
select col,
cast( regexp_replace( col, '\D+\s+(\d+).*','\1') as numeric) As field1,
regexp_replace( col, '\D+\s+\d+(\D*),*.*','\1') As field2,
cast( regexp_replace( col, '\D+\s+\d+\D*,*(\d*)','\1') As numeric) As field3
from table1
ORDER BY field1, field2, field3
;
select * from table1
order by
cast( regexp_replace( col, '\D+\s+(\d+).*','\1') as numeric),
regexp_replace( col, '\D+\s+\d+(\D*),*.*','\1'),
cast( regexp_replace( col, '\D+\s+\d+\D*,*(\d*)','\1') As numeric)
Demo: http://sqlfiddle.com/#!4/8f289/10
Upvotes: 1
Reputation: 73609
How about:
order by SUBSTRING(col_name, CHARINDEX(' ', col_name) + 1, len(col_name)-(CHARINDEX(' ', col_name)-1))
Here SUBSTRING(col_name, from_index, till_index)
gives me substring between these indexes, and using CHARINDEX
function I am finding indexes around second word of the string to extract it.
Please note, as par my understanding this will not use any index and can be slow if you have large data in the table.
Upvotes: 0