Here's a tip: Whenever you are having problems with the sort, add order by items to your select clause. this will enable you to see if what you are sorting by is actually what you want to sort by:
SELECT Section,
CASE WHEN PATINDEX('%[0-9]%',Section) > 1 THEN
LEFT(Section,PATINDEX('%[0-9]%',Section)-1)
ELSE
Section
END As alphabetical_sort, -- alphabetical sort
CASE WHEN PATINDEX('%[0-9]%',Section) > 1 THEN
CAST(SUBSTRING(Section,PATINDEX('%[0-9]%',Section),LEN(Section)) as float)
ELSE
NULL
END As Numeric_Sort
FROM dbo.Section
ORDER BY alphabetical_sort, Numeric_Sort
After I've got the sort correctly, All I had to do is move the case statements to the order by clause:
SELECT Section
FROM dbo.Section
ORDER BY
CASE WHEN PATINDEX('%[0-9]%',Section) > 1 THEN
LEFT(Section,PATINDEX('%[0-9]%',Section)-1)
ELSE
Section
END , -- Alphabetical sort
CASE WHEN PATINDEX('%[0-9]%',Section) > 1 THEN
CAST(SUBSTRING(Section,PATINDEX('%[0-9]%',Section),LEN(Section)) as float)
ELSE
NULL
END -- Numeric sort
Basically, You had 4 major problems:
- Your alphabetical sort expression assumed that every row have numbers in it.
- Your alphabetical sort expression contained the numbers as well as the text.
- Your numeric sort expression had both numeric and alphabetical values.
- Because of article 3, you couldn't cast your numeric sort expression to a numeric type, and this is why you would get you a string sort.
See this sql fiddle
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…