【问题标题】:Numeric order by varcharvarchar 的数字顺序
【发布时间】:2018-10-02 14:30:26
【问题描述】:

大家好,我正在尝试对我的 varchar 列进行排序。我几乎完成了它,但我找不到以下解决方案:

-999, -998, 0, 8A, 80, 80A, 90, A80, ADBA

目前是(见代码): -998, -999, 0, 8A, 80, 80A, 90, A80, ADBA

我只需要修复负值。有人有解决这个问题的办法吗?

 SELECT RANK_NUMBER FROM SHIPMENT_EVENT
    ORDER BY CASE WHEN ISNUMERIC(RANK_NUMBER) = 1 THEN RIGHT('0000000000' + RANK_NUMBER, 10) ELSE CASE 
                 WHEN LEFT(RANK_NUMBER, 1) LIKE '[0-9]' THEN RIGHT( 
                 '0000000000' 
                     + LEFT(SUBSTRING(RANK_NUMBER, PATINDEX('%[0-9.-]%', RANK_NUMBER 
                 ), 80 
                 ), 
                 PATINDEX 
                 ('%[^0-9.-]%', SUBSTRING(RANK_NUMBER, PATINDEX('%[0-9.-]%', 
                 RANK_NUMBER), 
                 80 
                 ) + 'X') -1), 10) 
                 ELSE RANK_NUMBER 
               END 
           END

【问题讨论】:

  • 订货中为什么8A小于80?它几乎看起来像十六进制排序,但这并不一致。你能解释一下排序这些值的逻辑吗?

标签: sql tsql numeric alphanumeric sql-order-by


【解决方案1】:

我希望是这样的:

order by cast(left(col, patindex('%[^-0-9]%', col + 'x') - 1) as decimal(20, 0))

【讨论】:

  • 如果我这样做,负值是固定的,但 A80 和 ADA 值会转换为 0。 (-999, -998, 0, A80, ADBA, 8A, 80, 80A, 90) 必须是(-999, -998, 0, 8A, 80, 80A, 90, A80, ADBA)
  • 我将其更改为: SELECT RANK_NUMBER FROM SHIPMENT_EVENT ORDER BY CASE WHEN cast(NULLIF(left(RANK_NUMBER, patindex('%[^-0-9]%', RANK_NUMBER + 'x') - 1), '') as int) IS NULL THEN 1 ELSE 0 END, cast(NULLIF(left(RANK_NUMBER, patindex('%[^-0-9]%', RANK_NUMBER + 'x') - 1), ' ') as int) 成功了,谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-02-03
  • 1970-01-01
  • 2011-01-04
  • 2010-09-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多