Basically, I am trying to sort a table by its name. The table is relatively big, but I am posting only one column, for sake of example. The Column is Station below
Station
===
ANTIL WELL 1
ANTIL WELL 2
BASELINE & CALIFORNIA WELL
EPA WELL 6
EPA WELL 7
EPA WELL 108
EPA WELL 109
EPA WELL 110
EPA WELL 111
EPA WELL 112
EPA WELL 108S
The sort above was achieved by me trying this:
order by left(station,LEN(station) -PATINDEX('%[^0-9]%',REVERSE(station))+1)
,CONVERT(int,REVERSE(LEFT(REVERSE(station), PATINDEX('%[^0-9]%',REVERSE(station)) - 1)))
However, I just can't sort that EPA WELL 108S. I need it to go between EPA WELL 108 and EPA WELL 109, I tried many many different ways.
Also the list of the stations goes on after EPA.
This solution is more reliable than the chosen answer. This answer may not give the expected answer if there is more than 1 number like 'EPA WELL 5 7' in station. This solution is padding the number with '0's so the comparison will consider all numbers 8 digits.
DECLARE @Table1 table([station] varchar(26))
INSERT INTO @Table1
([station])
VALUES
('ANTIL WELL 2'),
('ANTIL WELL 1'),
('BASELINE & CALIFORNIA WELL'),
('EPA WELL 7'),
('EPA WELL 6'),
('EPA WELL 108'),
('EPA WELL 109'),
('EPA WELL 110'),
('EPA WELL 111'),
('EPA WELL 112'),
('EPA WELL 108S'),
('EPA WELL 111108')
;
SELECT station
FROM @table1
ORDER BY
CASE WHEN station not like '%[0-9]%' THEN station ELSE
STUFF(station, PATINDEX('%[0-9]%',station), 0, replicate('0',
PATINDEX('%[0-9]%',station) - len(station) + PATINDEX('%[0-9]%',reverse(station)) + 6))
END
*GoatCD's answer will not give the correct order in my test data.
I need it to go between EPA WELL 108 and EPA WELL 109
Then you're not sorting it by name; you're sorting it by separate subcomponents that also happen to be incorporated in the name column, but in a different sequence. You have to create columns for each subcomponent and sort by the subcomponents:
Name sc1 sc2 sc3
EPA WELL 108 EPA WELL 108
EPA WELL 6 EPA WELL 6
EPA WELL 7 EPA WELL 7
EPA WELL 109 EPA WELL 109
EPA WELL 108s EPA WELL 108 s
Then you can use an ORDER BY clause like:
ORDER BY sc1, sc2, sc3
If you want to avoid duplicating data, remove the Name column and assemble your display name from subcomponents:
SELECT sc1 + ' ' + Convert(VarChar, sc2) + sc3 AS Name
It is fast and easy to catenate a name at runtime. It is neither fast nor easy to sort by variable-sized subcomponents of a VarChar at runtime.
来源:https://stackoverflow.com/questions/22461619/complex-sort-of-field-string-number-string