I need to sort a table of apartment numbers in SQL. For those unfamiliar, these are not necessarily numbers, but numerical ordering needs to be applied as though they were.
For example, a possible set of apartment numbers would be ordered as-follows:
1
10
101
101-A
1000
200
200A
2000
C
D
E-100
F
Doing ORDER BY CONVERT( int, ApartmentNumber )
wouldn't work because not all apartment-numbers are string-encoded decimal integers. Similarly doing ORDER BY ApartmentNumber
wouldn't work because it would place 101
after 1000
.
The other QAs on StackOverflow generally concern themselves with either a known fixed-format of value Sorting string column containing numbers in SQL? or doing the sort with error-handling: Sorting field by numerical value and lexicographical value
In my own project, a previous developer used this trick:
ORDER BY
RIGHT('00000000000000000000' + RTRIM( ApartmentNumber ), 20 ) ASC
...which feels even worse. Thing is: this trick is algorithmically sound - it just feels like a hack to have to have the database engine perform string allocations (multiple times too, if they don't optimize the concatenation and RTRIM
into a single string operation).
Another approach proffered on SO is:
ORDER BY
LEN( ApartmentNumber ),
ApartmentNumber
...however this yields this incorrect ordering of the input set:
1
C
D
F
10
101
200
1000
2000
200A
101-A
E-100
I'm using SQL Server 2012 locally (in 2008 (Level 100
) compatibility mode) and this application will be deployed to an Azure SQL server (Azure SQL V12).
UPDATE:
I've been considering some options, I think the "best" is to use a fixed-length char(10)
field instead of varchar(10)
and to ensure that the content of the field is always left-aligned, that way the sort-order will be ensured with a simple ORDER BY ApartmentNumber
.
UPDATE 2: I realised the above idea (char(10)
) doesn't solve the problem of 200A
needing to be sorted before 2000
. I think the best solution would be to normalize the values to a uniform integer representation and storing that int value in the database. The algorithm to do the conversion would be best (i.e. most succinctly) if it were not written in SQL.