Complex sort of field “string - number - string”

后端 未结 2 1389
夕颜
夕颜 2020-12-12 01:46

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



        
相关标签:
2条回答
  • 2020-12-12 02:17

    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.

    0 讨论(0)
  • 2020-12-12 02:37

    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.

    0 讨论(0)
提交回复
热议问题