Reputation: 3585
I have an old database with a list of books. Each book has a volume number. The volumes can be part 1 and part 2. So, I have books with these volume numbers:
1
2
3
...
29 (1)
29 (2)
30 (1)
30 (2)
I need to select all volumes in DESC order, ordering by the volume number column. Originally I did this dynamic casting:
SELECT * FROM volumenes ORDER BY volumen_numero * 1 DESC
Which worked great until it reached 30! For some reason, it now returns this:
30 (1)
30 (2)
29 (2)
29 (1)
... all sorted correctly from this point on
I tried replacing the parenthesis from the column value, like so:
ORDER BY CAST(replace(replace(volumen_numero,")",""), "(", "") as unsigned)
But I get the exact same result.
What I'm looking for is this order:
30 (2)
30 (1)
29 (2)
29 (1)
...
Here you have a working SQL Fiddle
Upvotes: 1
Views: 274
Reputation: 13725
You should debug in your select what happens. (Add the order expression to the select and verify it.)
I guess the space disturbs the integer conversion. (Probably the second part will be truncated.) If this assumption is true, you can fix it easily:
ORDER BY CAST(replace(replace(replace(volumen_numero,")",""), "(", "")," ","") as unsigned)
Upvotes: 1
Reputation: 1270523
The problem is that you are only sorting by the first number. Here is a more explicit approach:
order by substring_index(volumen_numero, ' ', 1) + 0,
substring_index(volumen_numero, ' ', -1)
The above will work as long as the volume number is one digit. You can handle longer volume numbers with:
order by substring_index(volumen_numero, ' ', 1) + 0,
length(substring_index(volumen_numero, ' ', -1)),
substring_index(volumen_numero, ' ', -1)
Or, if you prefer being cryptic and shorter:
order by volumen_numero + 0,
substring_index(volumen_numero, '(', -1) + 0
Upvotes: 1