That's because you are using a string based ID code, and expecting comparisons to work on the numeric bits.
They don't. String based comparisons work by comparing two strings character by character from the left had side until they find the first pair of different characters.
The whole comparison is then based on the difference between that pair of characters, no other characters in the strings are even looked at.
So if you have strings containing the numeric values "1", "2, "10", "19, "20", and "100" the sort order will be:
1
10
19
100
2
20
Not the numeric sequence you would expect.
And the character comparison uses the ASCII (for VARCHAR columns) or Unicode (for NVARCHAR columns) character set where '0' is less than 'A', which is less than 'a', and so on.
You would need to work out exactly what "sort oder" your various code values should have, establish the rules, and implement them manually in order for your current design to work. That isn't going to be at all easy, given that string handling in SQL is pretty basic.
Me? I wouldn't pregenerate codes, and I'd have a consistent system code code values which could be automated probably via a Computed Column.