使用类型字符串对字段进行排序但包含字符串和数字

时间:2016-03-02 04:58:23

标签: sql-server tsql

表格的字段为varchar(50)

此字段包含数字,字符串和混合,例如1001100121001b

我想编写q个查询,逐个字符地排序:

1001

1001b

10012

1 个答案:

答案 0 :(得分:0)

您可以使用模式拆分器将字符串拆分为数字和字符。以下是来自Dwain Camp article PatternSplitCM

-- PatternSplitCM will split a string based on a pattern of the form 
-- supported by LIKE and PATINDEX 
-- 
-- Created by: Chris Morris 12-Oct-2012 
CREATE FUNCTION [dbo].[PatternSplitCM]
(
       @List                VARCHAR(8000) = NULL
       ,@Pattern            VARCHAR(50)
) RETURNS TABLE WITH SCHEMABINDING 
AS 

RETURN
    WITH numbers AS (
        SELECT TOP(ISNULL(DATALENGTH(@List), 0))
            n = ROW_NUMBER() OVER(ORDER BY (SELECT NULL))
        FROM
        (VALUES (0),(0),(0),(0),(0),(0),(0),(0),(0),(0)) d (n),
        (VALUES (0),(0),(0),(0),(0),(0),(0),(0),(0),(0)) e (n),
        (VALUES (0),(0),(0),(0),(0),(0),(0),(0),(0),(0)) f (n),
        (VALUES (0),(0),(0),(0),(0),(0),(0),(0),(0),(0)) g (n)
    )

    SELECT
        ItemNumber = ROW_NUMBER() OVER(ORDER BY MIN(n)),
        Item = SUBSTRING(@List,MIN(n),1+MAX(n)-MIN(n)),
        [Matched]
    FROM (
        SELECT n, y.[Matched], Grouper = n - ROW_NUMBER() OVER(ORDER BY y.[Matched],n)
        FROM numbers
        CROSS APPLY (
            SELECT [Matched] = CASE WHEN SUBSTRING(@List,n,1) LIKE @Pattern THEN 1 ELSE 0 END
        ) y
    ) d
    GROUP BY [Matched], Grouper

您的最终查询将是:

;WITH tbl(string) AS(
    SELECT '10001' UNION ALL
    SELECT '100012' UNION ALL
    SELECT '10001b' UNION ALL
    SELECT 'b1000'
)
SELECT
    t.string,
    NumPart = MAX(CASE WHEN s.Matched = 0 THEN CAST(s.Item AS INT) END),
    CharPart = MAX(CASE WHEN s.Matched = 1 THEN s.Item END)
FROM tbl t
CROSS APPLY dbo.PatternSplitCM(string, '%[^0-9]%') s
GROUP BY t.string
ORDER BY
    NumPart, CharPart