【问题标题】:Ordering numeric like strings in T-SQL在 T-SQL 中对类似数字的字符串进行排序
【发布时间】:2013-03-19 12:25:30
【问题描述】:

我的表(称为抗原)中有字符串(称为等位基因),我无法按正确的顺序排序。

等位基因的代表性样本集可能:-

  • 01:01
  • 01:02
  • 02:01
  • 04:01
  • 09:01N
  • 10:01
  • 104:01
  • 105:01
  • 11:01N
  • 03:01:01
  • 03:01:02

我需要这些等位基因按以下顺序排列:-

  • 01:01
  • 01:02
  • 02:01
  • 03:01:01
  • 03:01:02
  • 04:01
  • 09:01N
  • 10:01
  • 11:01N
  • 104:01
  • 105:01

我无法将等位基因排序为字符串,因为 104:01 和 105:01 将出现在 11:01 之前。

我无法去掉“:”字符并进行数字排序,因为这会将 03:01:01 和 03:01:02 放在末尾,因为数值分别为 30101 和 30102。

我不知道如何实现这一点,如果有任何建议,我将不胜感激。

干杯

【问题讨论】:

  • 这一列还有更多这样的值吗??
  • 是的,Praveen,该列有数百个值。我只是选择了一个有代表性的样本来解释问题

标签: tsql sql-order-by


【解决方案1】:

假设最大字符数between/before/after : is 3,您可以使所有字符串值的长度和顺序相同,如下所示。不过看起来有点复杂!

Fiddle demo

;with cte as (
select val, charindex(':',val,1) index1, 
            charindex(':',val,charindex(':',val,1)+1) index2
from t
)
select val,right('000' + left(val,index1-1),3) + ':' +
           case when index2-index1>0 
                then  right('000' + substring(val,index1+1,index2-index1-1),3)
           else right('000' + substring(val,index1+1,len(val)),3) end + ':' +
           case when index2>0 
                then  right('000' + right(val, len(val) - index2),3)
           else '000' end As odr

from cte
order by odr

|      VAL |         ODR |
--------------------------
|    01:01 | 001:001:000 |
|    01:02 | 001:002:000 |
|    02:01 | 002:001:000 |
| 03:01:01 | 003:001:001 |
| 03:01:02 | 003:001:002 |
|    04:01 | 004:001:000 |
|   09:01N | 009:01N:000 |
|    10:01 | 010:001:000 |
|   11:01N | 011:01N:000 |
|   104:01 | 104:001:000 |
|   105:01 | 105:001:000 |

【讨论】:

  • 对不起,JohnD,但你说的点赞是什么意思?我假设这并不意味着将答案标记为正确。
  • @Kaf - 就在我以为我已经完全怀疑的时候,我在表中发现了一个带有 3 个“:”分隔符的等位基因: - 01:01:02:01 当前算法具有这个值放在 01:01 以上(注意,表格中没有 01:01:02)
  • Neil:你必须在cte 中获得Index3 并按照相同的程序构建等长字符串...感谢@JohnD 的支持!
  • @Neil 如果答案对您有帮助,请单击答案左上角 # 上方的向上箭头/三角形。查看常见问题解答部分“我如何在这里提问?” - 它有更详细的信息。
【解决方案2】:

使用

ORDER BY CAST (
             SUBSTR(Allelens
                    , 0
                    , CHARINDEX(Allelens, ':') - 1)
             AS INTEGER)

【讨论】:

    【解决方案3】:

    您想按冒号前的部分进行数字排序吗?如果是的话,应该这样做:

    select *
    from mytable
    order by cast(substring(col, 0, CHARINDEX(':', col)) as int)
    

    结果:

    01:01
    01:02
    02:01
    03:01:01
    03:01:02
    04:01
    09:01N
    10:01
    11:01N
    104:01
    105:01
    

    【讨论】:

    • 我认为它需要在 : 之后对数字进行第二次排序
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-11-14
    • 2021-04-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-07
    • 1970-01-01
    相关资源
    最近更新 更多