Tách các chữ cái khỏi các chữ số trong chuỗi ký tự chữ và số


9

Tôi có một chuỗi ký tự chữ và số làm đầu vào và tôi muốn nhận được hai kết quả từ nó:

  • một chuỗi trong đó tất cả các chữ số được loại bỏ

  • một số nguyên là tổng của tất cả các chữ số trong chuỗi đầu vào.

Ví dụ, đối với đầu vào này:

GR35hc7vdH35

Tôi muốn đầu ra sau:

| Col1.         |        Col2    |
----------------------------------
| GRhcvdH       |        23      |

Làm thế nào có thể làm điều này?

Câu trả lời:


8

SQL Server không hỗ trợ thay thế các mẫu của nhiều ký tự - vì vậy để thực hiện thông qua REPLACEsẽ có khả năng 10 thao tác.

Với ý nghĩ đó, một cách làm sẽ là CTE đệ quy để xử lý các chữ số 0-9 theo tuần tự.

Nó thực hiện thay thế và sau đó kiểm tra độ dài của chuỗi trước và sau để biết có bao nhiêu ký tự của số đó và những gì cần phải được thêm vào tổng số.

DECLARE @Input VARCHAR(8000) = 'GR35hc7vdH35';

WITH R(Level,Input,Accumulator,StringLength)
     AS (SELECT 0,
                Input,
                0,
                DATALENGTH(Input)
         FROM   (SELECT REPLACE(@Input, '0', '')) D(Input)
         UNION ALL
         SELECT NewLevel,
                NewInput,
                Accumulator + NewLevel * ( StringLength - NewStringLength ),
                NewStringLength
         FROM   R
                CROSS APPLY (SELECT Level + 1) C(NewLevel)
                CROSS APPLY (SELECT REPLACE(Input, NewLevel, '')) C2(NewInput)
                CROSS APPLY (SELECT DATALENGTH(NewInput)) C3(NewStringLength)
         WHERE  NewLevel <= 9)
SELECT Input       AS Col1,
       Accumulator AS Col2
FROM   R
WHERE  Level = 9;

Hoặc bạn có thể sử dụng CLR và các biểu thức chính quy (phiên bản tương thích SQL Server 2012).

using System;
using System.Data.SqlTypes;
using System.Collections;
using System.Text.RegularExpressions;

public partial class UserDefinedFunctions
{
    private static readonly Regex digitRegex = new Regex(@"[\d]", RegexOptions.Compiled);

    [Microsoft.SqlServer.Server.SqlFunction(FillRowMethodName = "FillRow",
                                            TableDefinition = @"Stripped NVARCHAR(MAX),
                                                                Total INT")]

    public static IEnumerable ReplaceAndTotalise(SqlString input)
    {
        if (!input.IsNull)
        {
            int total = 0;
            string stripped = digitRegex.Replace((string)input, match =>
            {
                total += int.Parse(match.Value);
                return string.Empty;
            });

            yield return new Tuple<string, int>(stripped, total);
        }
    }

    public static void FillRow(object resultObject, out SqlString stripped, out SqlInt32 total)
    {
        var result = (Tuple<string, int>)resultObject;
        stripped = result.Item1;
        total = result.Item2;

    }
}

Cách sử dụng ví dụ

SELECT Stripped,
       Total
FROM   [dbo].[ReplaceAndTotalise]('GR35hc7vdH35') 

5

Hãy thử như sau:

CREATE FUNCTION dbo.AlphaNumericSplitter 
(
    @string varchar(8000)
)
RETURNS TABLE
AS
RETURN  (
    WITH    Alphanumeric (col1)
    AS      (
            -- Put out string into a cte table
            SELECT @string
            ),
            Nmbrs (n)
    AS      (
            -- Numbers so we can split the string
            SELECT  TOP(LEN(@string))
                    ROW_NUMBER() OVER (ORDER BY (SELECT NULL))
            FROM    sys.all_objects AS o1
            CROSS
            JOIN    sys.all_objects AS o2
            ),
            y
    AS      (
            SELECT  N.n
                    a.col1,
                    N.x,
                    -- Get the numbers only
                    Numbers = TRY_CONVERT(int, N.x)
            FROM    Alphanumeric AS a
            CROSS 
            APPLY   (SELECT [x] = SUBSTRING(a.col1, n, 1), Nmbrs.n FROM Nmbrs) AS N
            )
    SELECT  z.Col1,
            Col2 = SUM(y.Numbers)
    FROM    y
    --  Get the letters only
    CROSS
    APPLY   (SELECT (SELECT x + '' FROM y WHERE Numbers IS NULL ORDER BY y.n FOR XML PATH(''))) AS z (Col1)
    GROUP   BY
            z.Col1);
GO

SELECT * FROM AlphaNumericSplitter('GR35hc7vdH35');

Các kết quả:

nhập mô tả hình ảnh ở đây


2

Loại

... r.s ...
cross apply (
  select s = sum(cast(substring(mycol,i,1) as int)) 
  from (select top(len(mycol)) i = row_number() over(order by (select null))
    from sys.all_objects,sys.all_objects) tally
  where substring(mycol,i,1) like '[0-9]'
) r

0

Sử dụng chức năng sau để trích xuất bảng chữ cái từ chuỗi

CREATE FUNCTION dbo.udf_GetAlphabets
(@strAlphaNumeric VARCHAR(256))
RETURNS VARCHAR(256)
AS
BEGIN
DECLARE @intAlpha INT
SET @intAlpha = PATINDEX('%[a-zA-Z]%', @strAlphaNumeric)
BEGIN
WHILE @intAlpha > 0
BEGIN
SET @strAlphaNumeric = STUFF(@strAlphaNumeric, @intAlpha, 1, '' )
SET @intAlpha = PATINDEX('%[a-zA-Z]%', @strAlphaNumeric )
END
END
RETURN ISNULL(@strAlphaNumeric,0)
END
GO

Sử dụng hàm sau để trích xuất số từ chuỗi

CREATE FUNCTION dbo.udf_GetNumeric
(@strAlphaNumeric VARCHAR(256))
RETURNS VARCHAR(256)
AS
BEGIN
DECLARE @intAlpha INT
SET @intAlpha = PATINDEX('%[^0-9]%', @strAlphaNumeric)
BEGIN
WHILE @intAlpha > 0
BEGIN
SET @strAlphaNumeric = STUFF(@strAlphaNumeric, @intAlpha, 1, '' )
SET @intAlpha = PATINDEX('%[^0-9]%', @strAlphaNumeric )
END
END
RETURN ISNULL(@strAlphaNumeric,0)
END
GO

Sử dụng truy vấn sau để trích xuất cả hai trong một lệnh:

SELECT dbo.udf_GetNumeric(column_name) Number, dbo.udf_GetAlphabets(column_name) Chars
from table_name
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.