【问题标题】:Alphanumeric Sorting in Sql Server 2008Sql Server 2008 中的字母数字排序
【发布时间】:2016-09-12 11:22:15
【问题描述】:

谁能帮我解决这个问题?
我有一个要排序的动态模式列表,它包含字母数字值和字母。

CREATE TABLE dbo.Pattern (Pattern varchar(50) NULL)
INSERT INTO dbo.Pattern (Pattern) VALUES ('A11')
INSERT INTO dbo.Pattern (Pattern) VALUES ('A12')
INSERT INTO dbo.Pattern (Pattern) VALUES ('A8')
INSERT INTO dbo.Pattern (Pattern) VALUES ('A2')
INSERT INTO dbo.Pattern (Pattern) VALUES ('B6')
INSERT INTO dbo.Pattern (Pattern) VALUES ('B21')
INSERT INTO dbo.Pattern (Pattern) VALUES ('B10')
INSERT INTO dbo.Pattern (Pattern) VALUES ('B3')
INSERT INTO dbo.Pattern (Pattern) VALUES ('B100')
INSERT INTO dbo.Pattern (Pattern) VALUES ('B2')
INSERT INTO dbo.Pattern (Pattern) VALUES ('AA')
INSERT INTO dbo.Pattern (Pattern) VALUES ('BA')
INSERT INTO dbo.Pattern (Pattern) VALUES ('A20')
INSERT INTO dbo.Pattern (Pattern) VALUES ('AB')
INSERT INTO dbo.Pattern (Pattern) VALUES ('BB')

SELECT Pattern FROM dbo.Pattern ORDER BY Pattern

DROP Table dbo.Pattern

结果如下所示:

 A11
 A12
 A2
 A20
 A8
 AA
 AB
 B10
 B100
 B2
 B21
 B3
 B6
 BA
 BB

但我只想展示这样的结果:

AA
A1
A2
A8
A11
A12
A20
AB
BA
B2
B3
B6
B10
B21
B100
BB

【问题讨论】:

  • 样本数据加 1
  • 你能定义你想要的结果背后的逻辑吗?为什么AA 出现在B100 之后? AAABA1 之间哪个会先出现?为什么?如果你能定义逻辑,我打赌你就能轻松回答自己的问题。
  • @TabAlleman,我已经编辑了应该为模式排序输出的结果内容。

标签: sql sql-server sql-order-by


【解决方案1】:
SELECT Pattern
FROM dbo.Pattern 
ORDER BY LEFT(Pattern,1), 
        CASE WHEN SUBSTRING(Pattern,2,LEN(Pattern)) LIKE '%[0-9]%' THEN CAST(SUBSTRING(Pattern,2,LEN(Pattern)) as int) 
            WHEN SUBSTRING(Pattern,2,LEN(Pattern)) = 'A' THEN 0
            ELSE 10000000 END,
            SUBSTRING(Pattern,2,LEN(Pattern))

将输出:

Pattern
AA
A2
A8
A11
A12
A20
AB
BA
B2
B3
B6
B10
B21
B100
BB

【讨论】:

    【解决方案2】:
    SELECT Pattern
    FROM dbo.Pattern
    ORDER BY CASE WHEN PATINDEX('%[0-9]%', Pattern) > 0
                  THEN LEFT(Pattern, PATINDEX('%[0-9]%', Pattern)-1)
                  ELSE Pattern
             END,
             CASE WHEN PATINDEX('%[0-9]%', Pattern) > 0
                  THEN CONVERT(INT, SUBSTRING(Pattern, PATINDEX('%[0-9]%', Pattern), LEN(Pattern)))
                  ELSE 0
             END
    

    发帖前请搜索网络和Stack Overflow。

    参考:http://www.essentialsql.com/use-sql-server-to-sort-alphanumeric-values/

    【讨论】:

    • 它返回Invalid length parameter passed to the LEFT or SUBSTRING function. 错误。 AABA的值抛出错误,因为它们没有数值,所以LEFT('AA', 0 - 1)抛出错误。
    • Msg 537, Level 16, State 2, Line 1 传递给 LEFT 或 SUBSTRING 函数的长度参数无效。
    • @ayakamacy 我更新了我的答案以使用CASE 表达式来处理仅包含字母的模式。
    • @Arulkumar 我更新了我的答案先生,请看一下。
    【解决方案3】:

    对于您的示例数据,这很接近:

    order by left(pattern, patindex('%[0-9]%', pattern)),
             patindex('%[0-9]%', pattern),
             len(pattern) asc,
             pattern
    

    但是,您希望所有 alpha 都排在最后,所以需要 case(我认为):

    order by left(pattern, patindex('%[0-9]%', pattern)),
             (case when pattern like '%[0-9]%'
                   then patindex('%[0-9]%', pattern)
                   else 999
              end),
             len(pattern) asc,
             pattern
    

    【讨论】:

    • 它没有按照上面的要求返回输出。为什么?
    • 这个逻辑意味着B1 会在A10 之前,因为它的长度更短。
    • @Suraz 。 . .你已经有了答案,但我还是修正了这个答案。
    【解决方案4】:

    我会分开 alpha 和 num 部分:

    ORDER BY
        CASE WHEN PATINDEX('%[0-9]%', Pattern)=0 THEN 1 ELSE 0 END,--Put no-nums last
        CASE WHEN PATINDEX('%[0-9]%', Pattern) != 0 THEN LEFT(Pattern, PATINDEX('%[0-9]%', Pattern)-1) ELSE Pattern END,
        CASE WHEN PATINDEX('%[0-9]%', Pattern) != 0 THEN SUBSTRING(Pattern, PATINDEX('%[0-9]%', Pattern), LEN(Pattern)) END
    

    【讨论】:

      【解决方案5】:

      使用交叉应用来简化行内计算

      select pattern
      from pattern
      cross apply (
          select leftLen = isnull(nullif(patindex('%[0-9]%', pattern),0) - 1, len(pattern))
                ,totalLen = len(pattern)  
          ) c
      order by 
       case leftLen when totalLen then 2 else 1 end,
       left(Pattern, leftLen),
       cast(right(Pattern, totalLen-leftLen) as int)
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-12-12
        • 2018-08-28
        • 2021-09-03
        • 2015-07-13
        • 2023-03-26
        • 1970-01-01
        相关资源
        最近更新 更多