Complex sort of field “string - number - string”

纵饮孤独 提交于 2019-11-27 08:18:19

问题


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.


回答1:


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.




回答2:


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!