Reputation: 72616
I have a varchar column conteining a code, this code could by only numbers, or number prefixed by a char for example i have a column containing this data :
+------+
| Code |
+------+
| 1 |
| C1 |
| 2 |
| 3 |
| C3 |
| F3 |
| F1 |
| F17 |
| C9 |
| C10 |
| C47 |
| C100 |
| C134 |
| A234 |
|C1245 |
| 10 |
| 100 |
+------+
And so on ...
I want to sort this column by this rules :
I want to achieve a resultset ordered like this :
+------+
| Code |
+------+
| 1 |
| 2 |
| 3 |
| 10 |
| 100 |
| A234 |
| C1 |
| C3 |
| C9 |
| C10 |
| C47 |
| C100 |
| C134 |
|C1245 |
| F1 |
| F3 |
| F17 |
+------+
How can i get a resultset ordered with this criteria ? I've tried with a query like this :
SELECT Code FROM Code_List ORDER BY case when Code like '%[a-z]%' then 99999999999999999999999999999999 else convert(decimal, Code) end
But i get a result that order first the number and then the prefixed number but the alpha prefixed number is ordered like char and not in the manner i want it...
The only numeric record should be ordered following the rules of the numeric order and no the character order so if the only numeric record are :
+------+
| Code |
+------+
| 1 |
| 47 |
| 2 |
| 3 |
| 6 |
| 100 |
| 112 |
| 10 |
I want to get :
+------+
| Code |
+------+
| 1 |
| 2 |
| 3 |
| 6 |
| 10 |
| 47 |
| 100 |
| 112 |
The Database is Microsoft SQL Server.
Upvotes: 6
Views: 7075
Reputation: 77657
Assuming there's no spaces before the values and there can only be 1-char prefix:
ORDER BY
CASE WHEN LEFT(Code, 1) BETWEEN '0' AND '9' THEN ' ' ELSE LEFT(Code, 1) END,
CAST(STUFF(Code, 1, CASE WHEN LEFT(Code, 1) BETWEEN '0' AND '9' THEN 0 ELSE 1 END, '') AS int)
Alternatively, the second criterion could be rewritten like this:
CAST(STUFF(Code, 1, PATINDEX('[^0-9]%', Code), '') AS int)
PATINDEX('[^0-9]%', Code)
returns 1 if it finds a non-numeric character at the beginning of Code
, and 0 otherwise. As a result, STUFF
either removes 1 character, or none, i.e. same as previously.
Upvotes: 4
Reputation: 31250
CASE
WHEN ISNUMERIC(Col) = 1 THEN '@'
Else LEFT(Col, 1)
END
,CASE
WHEN ISNUMERIC(Col) = 1 THEN Convert(int, Col)
Else Convert(int, RIGHT(Col, LEN(Col) - 1))
END
Upvotes: 4
Reputation: 5119
SELECT Code FROM Code_List ORDER BY Code, CASE WHEN ISNUMERIC(SUBSTRING(Code,1,1)) = 1 THEN CODE ELSE SUBSTRING(Code,2,LEN(Code)-1) END
Obviously assuming that only the first digit can be alpha
Upvotes: 0