根据特殊字符拆分数字

时间:2018-04-10 06:28:16

标签: sql-server sql-server-2008 sql-server-2016

我有一个栏目如下:

numbers
---------
225/271-2001  
5565/2233-123
1392551-6,X117

规则是:基于短划线( - )和斜杠(/)分隔数字。应删除逗号(如果存在)。“X”被视为扩展将保持原样。我需要将其分开,如下所示。 我明白,两种模式都不同。但是,我可以在编写查询时将其视为独立。 我想将这些数字拆分如下:

number1     |      number2
---------------------------
2252001           2712001
5565123           2233123
1392551X117       1392556X117

我尝试使用以下查询:

SELECT 
    ID, number
    , STUFF(
        LEFT(number,CHARINDEX('-',number)-1),
        LEN(LEFT(number,CHARINDEX('-',number)))-LEN(RIGHT(number,CHARINDEX('-',REVERSE(number))-1)),
        LEN(RIGHT(number,CHARINDEX('-',REVERSE(number))-1)),
        RIGHT(number,CHARINDEX('-',REVERSE(number))-1)
    ) 
    , SUBSTRING(number,CHARINDEX('/',number)+1,LEN(number)) AS [2ndnumber]
FROM [tablename] 
WHERE numbers LIKE '[0-9][0-9][0-9]/[0-9][0-9][0-9]-[0-9][0-9][0-9][0-9]'

但是,我没有按预期得到结果。我做错了什么?

3 个答案:

答案 0 :(得分:0)

您对/,的号码有不同的规则。所以你必须划分你的查询。这是一种方式:

declare @t table (numbers varchar(20))
insert into @t
values ('225/271-2001')
    , ('5565/2233-123'), ('1392551-6,X117')

select
    number1 = left(numbers, ci1 - 1) + right(numbers, len(numbers) - ci2)
    , number2 = substring(numbers, ci1 + 1, ci2 - ci1 - 1) + right(numbers, len(numbers) - ci2)
from
    @t
    cross apply (select ci1 = charindex('/', numbers), ci2 = charindex('-', numbers)) a
where
    charindex('/', numbers) > 0

union all

select
    left(numbers, ci1 - 1) + right(numbers, len(numbers) - ci2)
    , left(numbers, ci1 - 1 - (ci2 - ci1 - 1)) + substring(numbers, ci1 + 1, ci2 - ci1 - 1) + right(numbers, len(numbers) - ci2)
from
    @t
    cross apply (select ci1 = charindex('-', numbers), ci2 = charindex(',', numbers)) a
where
    charindex(',', numbers) > 0

输出

number1        number2
----------------------------
2252001        2712001
5565123        2233123
1392551X117    1392556X117

答案 1 :(得分:0)

请尝试以下操作,这可能会有所帮助。

CREATE TABLE #temp(ID INT, number varchar(200))

INSERT INTO #temp VALUES(1,'225/271-2001')
INSERT INTO #temp VALUES(2,'5565/2233-123')
INSERT INTO #temp VALUES(3,'1392551-6,X117')
INSERT INTO #temp VALUES(4,'13925515-65,X119')

SELECT ID,number
    ,CASE   -- When the pattern is '#/#-#'
            WHEN CHARINDEX('/',number) > 0 AND CHARINDEX('-',number) > CHARINDEX('/',number) 
                THEN CAST(SUBSTRING(number,1,CHARINDEX('/',number)-1) AS VARCHAR(50))
                    + CAST(SUBSTRING(number,CHARINDEX('-',number)+1,LEN(number)) AS VARCHAR(50))
            -- When the pattern is '#-#,#'
            WHEN CHARINDEX('-',number) > 0 AND CHARINDEX(',',number) > CHARINDEX('-',number) 
                THEN CAST(SUBSTRING(number,1,CHARINDEX('-',number)-1) AS VARCHAR(50))
                    + CAST(SUBSTRING(number,CHARINDEX(',',number)+1,LEN(number)) AS VARCHAR(50))
            ELSE number
        END [1st number]
    ,CASE   -- When the pattern is '#/#-#'
            WHEN CHARINDEX('/',number) > 0 AND CHARINDEX('-',number) > 0 
                THEN CAST(REPLACE(SUBSTRING(number,CHARINDEX('/',number)+1,LEN(number)),'-','') AS VARCHAR(50))         
            -- When the pattern is '#-#,#'
            WHEN CHARINDEX('-',number) > 0 AND CHARINDEX(',',number) > CHARINDEX('-',number) 
                    THEN LEFT(CAST(SUBSTRING(number,1,CHARINDEX('-',number)-1) AS VARCHAR(50)),(CHARINDEX('-',number)-1)-LEN(RIGHT(LEFT(number,CHARINDEX(',',number)-1),CHARINDEX(',',number)-1-CHARINDEX('-',number))))
                        + CAST(REPLACE(SUBSTRING(number,CHARINDEX('-',number)+1,LEN(number)),',','') AS VARCHAR(50))
            ELSE number
        END [2nd number]
FROM #temp 

输出:

ID    number              1st number      2nd number     
----- ------------------- --------------- ---------------
1     225/271-2001        2252001         2712001
2     5565/2233-123       5565123         2233123
3     1392551-6,X117      1392551X117     1392556X117
4     13925515-65,X119    13925515X119    13925565X119

答案 2 :(得分:0)

此查询应提供预期结果。使用xml格式进行简单查询。

CREATE TABLE #temp(ID INT, number varchar(200))

INSERT INTO #temp VALUES(1,'225/271-2001')
INSERT INTO #temp VALUES(2,'5565/2233-123')
INSERT INTO #temp VALUES(3,'1392551-6,X117')

;WITH Split_Names (ID,xmlname)
AS
(
    SELECT ID, 
    xmlname= CASE WHEN CHARINDEX(',',number)=0      
                  THEN CONVERT(xml,'<Names><name>'  
                               + REPLACE(REPLACE(REPLACE(number,'-', '<?name><name>'),'/', '</name><name>'),'?','/') + '</name></Names>') 
                  WHEN CHARINDEX(',',number)>0  
                  THEN CONVERT(xml,'<Names><name>'  
                               + REPLACE(REPLACE(REPLACE(
                                 REPLACE(REPLACE(concat(LEFT(number,(CHARINDEX('-',number)-1)),CAST('/' as char(1)),LEFT(number,(CHARINDEX('-',number)-2)),SUBSTRING(number,CHARINDEX('-',number)+1,1),',',substring(number,CHARINDEX(',',number)+1,LEN(number))),'-','/'),',','-')
                                 ,'-', '<?name><name>'),'/', '</name><name>'),'?','/') + '</name></Names>') 
             END
    FROM #temp
)
select xmlname.value('/Names[1]/name[1]','varchar(100)')+ xmlname.value('/Names[1]/name[3]','varchar(100)') NUMBER1,
       xmlname.value('/Names[1]/name[2]','varchar(100)')+ xmlname.value('/Names[1]/name[3]','varchar(100)') NUMBER2
from Split_Names
drop table #temp