Provided that the drawing number always consists of 3 parts, and assuming that you just want to sort by the middle component numerically ascending, you can (ab)use the PARSENAME
function as mentioned here to expedite splitting up the components of the numbers (The dashes need to be replaced by dots to trick the function into thinking it is a fully qualified name):
SELECT
tblDrawings.*
FROM
tblDrawings
WHERE
(((tblDrawings.AreaNo) = "21"))
ORDER BY CAST(PARSENAME(REPLACE(DrawingNo, '-', '.'), 2) AS BIGINT) ASC;
Fiddle here
(Parsename only works with up to 4 parts, and ordering is from right to left)
Edit
You are probably going to have to analyze all of the data and work out the exact ordering required before your query can be finalized. Some ideas, FWIW:
- The
parsename
hack won't work if you have a variable number of components - suggest you look at pulling a component splitting UDF across to your db like this one
- From a sanity and DRY point of view, you probably don't want to do all of this in one step - a CTE will make life easier as you pass the output of one transformation of data to the next.
- You can try a padding technique like below to try and address mixed numeric / non-numeric ordering. To accommodate the alpha suffixes, I'm guessing however that the padding needs to be both left and right of the original value, with the right padding reserved for non-numeric suffixes padding to the right
- You can do conditional ordering using a
ORDER BY CASE WHEN ... THEN ... ELSE ... END
, although note that all branches must return the same type.
Example of the padding idea 'objective':
xxx1x
xx11x
x111x
x111A
x112x
WITH cte as
(
SELECT
*,
PARSENAME(REPLACE(DrawingNo, '-', '.'), 3) as [3FromRight],
PARSENAME(REPLACE(DrawingNo, '-', '.'), 2) as [2FromRight],
PARSENAME(REPLACE(DrawingNo, '-', '.'), 1) as [1FromRight]
FROM tblDrawings
)
SELECT *
FROM cte
ORDER BY
REPLICATE('x',12-LEN([2FromRight])) + [2FromRight] + REPLICATE('x', 1)
ASC;
The number of replicated x's in "12-" and "1" would need to be adjusted to count the number of numeric and non-numeric chars and then adjust the padding before and afterwards. So using another query nesting / cte would probably needed to count the number of chars in the split components.