从字符串中拆分数字

时间:2015-01-26 09:35:43

标签: sql sql-server tsql

我有这样的表

4-Documento d’identità-3-Attestato di Rischio-2-Carta di Circolazione
10-Contrassegno
12-Documenti di annullo polizza-10-Contrassegno
10-Contrassegno
12-Documenti di annullo polizza-10-Contrassegno

我想将每一行拆分成这样的

4-3-2
10
12-10
10
12-10

5 个答案:

答案 0 :(得分:0)

试试这个

DECLARE @table AS TABLE
    (
      ID INT IDENTITY(1, 1) ,
      SomeText VARCHAR(500)
    )
INSERT  INTO @table
        ( SomeText )
VALUES  ( '4-Documento d’identità-3-Attestato di Rischio-2-Carta di Circolazione' ),
        ( '10-Contrassegno' ),
        ( '12-Documenti di annullo polizza-10-Contrassegno' ),
        ( '10-Contrassegno' ),
        ( '12-Documenti di annullo polizza-10-Contrassegno' );
WITH    cte
          AS ( SELECT   n = 1
               UNION ALL
               SELECT   n + 1
               FROM     cte
               WHERE    n <= 100
             ),
        SplitToChr
          AS ( SELECT   T.ID ,
                        SUBSTRING(T.SomeText, cte.n, 1) AS Chr
               FROM     @table AS T
                        JOIN cte ON DATALENGTH(T.SomeText) >= cte.n
                                    AND SUBSTRING(T.SomeText, cte.n, 1) LIKE '[0-9-]'
             )
    SELECT   T.ID ,
            REVERSE(SUBSTRING(REVERSE(T.FInal),2,LEN(T.FInal))) AS Final
    FROM    ( SELECT  DISTINCT
                        o.ID ,
                        REPLACE(( SELECT    '' + chr
                                  FROM      SplitToChr AS i
                                  WHERE     i.id = o.id
                                FOR
                                  XML PATH('')
                                ), '--', '-') AS FInal
              FROM      SplitToChr AS o
            ) AS T

答案 1 :(得分:0)

样本表

CREATE TABLE #TEMP(STRINGCOLUMN NVARCHAR(MAX))

INSERT INTO #TEMP
SELECT '4-Documento d’identità-3-Attestato di Rischio-2-Carta di Circolazione'
UNION ALL
SELECT '10-Contrassegno'
UNION ALL
SELECT '12-Documenti di annullo polizza-10-Contrassegno'
UNION ALL
SELECT '10-Contrassegno'
UNION ALL
SELECT '12-Documenti di annullo polizza-10-Contrassegno'

如果您需要简单的查询,可以使用函数

<强>功能

CREATE FUNCTION [dbo].[ConvertToNumber]
(@strAlphaNumeric VARCHAR(256))
RETURNS VARCHAR(256)
AS
BEGIN    
SET @strAlphaNumeric = LEFT(@strAlphaNumeric,
LEN(@strAlphaNumeric) - CHARINDEX('-', REVERSE(@strAlphaNumeric)) + 0)
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

您的最终查询

SELECT DBO.ConvertToNumber(STRINGCOLUMN)STRINGCOLUMN
FROM #TEMP

<强> RESULT

enter image description here

答案 2 :(得分:0)

首先使用此分裂功能

CREATE FUNCTION [dbo].[fnSplitString] ( @string NVARCHAR(MAX)
,                                       @delimiter CHAR(1) )
RETURNS @output TABLE ( splitdata NVARCHAR(MAX) )
BEGIN
    DECLARE @start INT
    ,       @end   INT
    SELECT @start = 1
    ,      @end = CHARINDEX(@delimiter, @string)
    WHILE @start < LEN(@string) + 1
    BEGIN
        IF @end = 0
            SET @end = LEN(@string) + 1

        INSERT INTO @output ( splitdata                                 )
        VALUES              ( SUBSTRING(@string, @start, @end - @start) )
        SET @start = @end + 1
        SET @end = CHARINDEX(@delimiter, @string, @start)

    END
    RETURN
END

然后使用此代码

CREATE TABLE #t10 ( id  int identity(1,1)
,                   num int )
INSERT INTO #t10
select *
from dbo.fnSplitString ('4-Documento d’identità-3-Attestato di Rischio-2-Carta di Circolazione','-')
WHERE ISNUMERIC(splitdata)=1
DECLARE @x int = 1
DECLARE @y varchar(10)=''
DECLARE @q varchar(10)
WHILE @x<=(SELECT count(*)
    from #t10)
BEGIN
    SET @q=(SELECT num
    FROM #t10
    WHERE id = @x )
    set @y=@y+@q+'-'
    SET @x=@x+1
END
SELECT left(ltrim(@y),len(@y)-1)
--SELECT * FROM #t10
--drop table #t10

答案 3 :(得分:0)

这有点乱,但它完成了工作:-)

            CREATE TABLE dbo.Documents (
            Details VARCHAR(1000)
            );


            GO

            INSERT INTO dbo.Documents
            VALUES ('4-Documento d’identità-3-Attestato di Rischio-2-Carta di Circolazione'),
                   ('10-Contrassegno'),
                   ('12-Documenti di annullo polizza-10-Contrassegno'),
                   ('10-Contrassegno'),
                   ('12-Documenti di annullo polizza-10-Contrassegno');



             SELECT CASE WHEN (FirstLine + SecondLine +  ThirdLine) LIKE '%-' 
                    THEN LEFT(FirstLine + SecondLine +  ThirdLine, LEN(FirstLine + SecondLine +  ThirdLine) -1)
                    ELSE (FirstLine + SecondLine +  ThirdLine) END AS CleanData
             FROM (  

               SELECT 
                LEFT(Details, CHARINDEX('-', Details)) AS FirstLine,
             REPLACE(CASE 
                        WHEN REPLACE(  REPLACE( LEFT(Details,CHARINDEX('-', Details, CHARINDEX('-', Details )+1)+2)     ,    LEFT(Details, CHARINDEX('-', Details, CHARINDEX('-', Details)+1)),    ''), LEFT(Details, CHARINDEX('-', Details)),  '') LIKE '%[0-9]' THEN   REPLACE(  REPLACE( LEFT(Details,CHARINDEX('-', Details, CHARINDEX('-', Details )+1)+2)     ,    LEFT(Details, CHARINDEX('-', Details, CHARINDEX('-', Details)+1)),    ''), LEFT(Details, CHARINDEX('-', Details)),  '') + '-'
               ELSE  REPLACE( LEFT(Details,CHARINDEX('-', Details, CHARINDEX('-', Details )+1)+2)     ,    LEFT(Details, CHARINDEX('-', Details, CHARINDEX('-', Details)+1)),    '')
               END , LEFT(Details, CHARINDEX('-', Details)),  '') AS SecondLine,
               CASE  WHEN REVERSE(LEFT(REVERSE(Details), CHARINDEX('-', REVERSE(Details))+2)) LIKE '-%'
                THEN LEFT(REVERSE(LEFT(REVERSE(Details), CHARINDEX('-', REVERSE(Details))+2)), 3) ELSE '' END  AS ThirdLine
               FROM dbo.Documents 
               ) AS A;

答案 4 :(得分:-1)

以更简单的方式执行此操作的另一种方式。创建function以从字符串中删除alphabets

Create FUNCTION dbo.RemoveAlphabets (@string VARCHAR(256))
returns VARCHAR(256)
  BEGIN
      IF @string  IS NULL
        RETURN NULL

      DECLARE @Result VARCHAR(256)='',@len INT = Len(@string ),@cnt INT=1

      WHILE @cnt <= @len
        BEGIN
            DECLARE @parse INT
            SET @parse = Ascii(Substring(@string , @cnt, 1))

            IF @parse BETWEEN 48 AND 57 or @parse =45
             SET @Result =  @Result + Char(@parse) 

            SET @cnt = @cnt + 1
        END
        select @result= replace(@Result,'--','-')
      RETURN left(@result,case when right(@Result,1)='-' then len(@Result)-1 else len(@result) end) 
  END 

如果字符串中的数字总是被&#39; - &#39;然后用此替换return语句。

 RETURN left(@result,len(@Result)-1) 

执行功能

select dbo.RemoveAlphabets
('4-Documento d’identità-3-Attestato di Rischio-2-Carta di Circolazione')

结果 4-3-2