【问题标题】:SQL Server : String convert Numeric and sorting issueSQL Server:字符串转换数字和排序问题
【发布时间】:2014-11-14 14:32:25
【问题描述】:

当我选择时,会显示一列。

我有一个下面的示例代码

C*12:03:01:01
C*12:03:01:02
C*12:03:06
C*12:109
C*12:110
C*12:111
C*12:23

应该有:分隔符。

并且在排序时应该对每个级别进行排序

例如第一级 12 都是一样的,所以排序是一样的 第二级 03, 03, 23, 109, 110,111 类似数字,然后是第三级 ...

所以应该如下所示

C*12:03:01:01
C*12:03:01:02
C*12:03:06
C*12:23
C*12:109
C*12:110
C*12:111

我已尝试删除所有字符并仅显示具有以下功能的数字

CREATE FUNCTION [dbo].[fn_StripCharacters]
(
    @String NVARCHAR(MAX), 
    @MatchExpression VARCHAR(255)
)
RETURNS NVARCHAR(MAX)
AS
BEGIN
    SET @MatchExpression =  '%['+@MatchExpression+']%'

    WHILE PatIndex(@MatchExpression, @String) > 0
        SET @String = Stuff(@String, PatIndex(@MatchExpression, @String), 1, '')

RETURN @String

END

当我尝试时

select dbo.fn_StripCharacters(DATA.AlleleName, '^0-9') 
from @temp
where CAST(dbo.fn_StripCharacters(DATA.AlleleName, '^0-9') AS INT)

然后它会显示

1223
12109
12110
12111
120306
12030101
12030102

所以我改变主意每个级别(由 : 分隔)最多只有 3 个字符。

你们知道制作方法吗

012:003:001:001
012:003:001:002
012:003:006:000
012:109:000:000
012:110:000:000
012:111:000:000
012:023:000:000

然后,如果我删除 : 并进行排序,它可能会起作用。

你们有什么更好的主意吗?谢谢!

【问题讨论】:

    标签: sql-server tsql sorting delimiter natural-sort


    【解决方案1】:

    在您的示例中,我认为您可以让 parsename() 为您完成工作:

    order by parsename(replace(col, ':', '.'), 4),
             cast(parsename(replace(col, ':', '.'), 3) as int),
             cast(parsename(replace(col, ':', '.'), 2) as int),
             cast(parsename(replace(col, ':', '.'), 1) as int)
    

    你的例子都有四个部分,所以这应该有效。此外,第一个元素看起来(从您的示例中)可以按字母顺序排序。

    【讨论】:

    • @clear.choi 。 . .我将答案更新为数据库正确。
    【解决方案2】:

    您可以编写一个函数,该函数将返回在给定位置由特定分隔符分割的字符串的一部分。示例:

    alter function [dbo].[f_Split]
        (
            @List nvarchar(max),
            @SplitOn varchar(5),
            @Position int
        )  
        RETURNS nvarchar(250)
        AS  
        BEGIN 
            declare @Index int = 0
            declare @Value nvarchar(250) = ''
    
            while (Charindex(@SplitOn, @List) > 0) and @Index != @Position
                begin
                    set @Value = ltrim(rtrim(substring(@List,1,charindex(@SplitOn,@List)-1)))
                    set @List = substring(@List,charindex(@SplitOn,@List)+len(@SplitOn),len(@List))
    
                    set @Position = @Position - 1
                end
    
            if @Index != @Position
                set @Value = ''
    
            return @Value
        END
    
    GO
    

    然后您可以像这样在查询中使用它:

    declare @temp table (col varchar(50))
    
    insert into @temp (col) values ('C*12:03:01:01')
    insert into @temp (col) values ('C*12:03:01:02')
    insert into @temp (col) values ('C*12:03:06')
    insert into @temp (col) values ('C*12:23')
    insert into @temp (col) values ('C*12:109')
    insert into @temp (col) values ('C*12:110')
    insert into @temp (col) values ('C*12:111')
    
    select 
        *
    from 
        @temp 
    order by
        dbo.f_split('C*12:03:01:01', ':', 5),
        dbo.f_split('C*12:03:01:01', ':', 4),
        dbo.f_split('C*12:03:01:01', ':', 3),
        dbo.f_split('C*12:03:01:01', ':', 2),
        dbo.f_split('C*12:03:01:01', ':', 1)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-11-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-10-02
      相关资源
      最近更新 更多