2016-12-10 2 views
1

を行に文字列:SQL Serverの:スプリット以下のデータを有効にする方法

CODE COMBINATION USER 
1111.111.11.0  KEN 
1111.111.11.0  JIMMY 
666.778.0.99  KEN 
888.66.77.99  LIM(JIM) 
888.66.77.99  JIMMY 

CODE COMBINATION USER 
1111.111.11.0  KEN; JIMMY 
666.778.0.99  KEN 
888.66.77.99  LIM(JIM); JIMMY 

私は、SQL Server 2016年に、これは、分割文字列関数で行うことができます知っているが、私の生産SQL Serverの2014

答えて

2

と機能の上に呼び出すことによって、あなたのテーブルの上に照会、あなたが分割される文字列と区切り文字を供給することができます。さらに、二次処理に非常に役立つシーケンス番号が得られます。

Select [CODE COMBINATION] 
     ,[USER] = B.RetVal 
From YourTable A 
Cross Apply [dbo].[udf-Str-Parse](A.[USER],';') B 

戻り

enter image description here

解析UDF

CREATE FUNCTION [dbo].[udf-Str-Parse] (@String varchar(max),@Delimiter varchar(10)) 
Returns Table 
As 
Return ( 
    Select RetSeq = Row_Number() over (Order By (Select null)) 
      ,RetVal = LTrim(RTrim(B.i.value('(./text())[1]', 'varchar(max)'))) 
    From (Select x = Cast('<x>'+ Replace(@String,@Delimiter,'</x><x>')+'</x>' as xml).query('.')) as A 
    Cross Apply x.nodes('x') AS B(i) 
); 
--Select * from [dbo].[udf-Str-Parse]('Dog,Cat,House,Car',',') 
--Select * from [dbo].[udf-Str-Parse]('John Cappelletti was here',' ') 

もう1つのオプションがParse-Row UDFです。解析された文字列を1行で返します。現在9ポジションですが、伸縮は簡単です。

Select [CODE COMBINATION] 
     ,B.* 
From YourTable A 
Cross Apply [dbo].[udf-Str-Parse-Row](A.[USER],';') B 

戻り

enter image description here

解析行UDFに

CREATE FUNCTION [dbo].[udf-Str-Parse-Row] (@String varchar(max),@Delimiter varchar(10)) 
Returns Table 
As 
Return (
    Select Pos1 = xDim.value('/x[1]','varchar(max)') 
      ,Pos2 = xDim.value('/x[2]','varchar(max)') 
      ,Pos3 = xDim.value('/x[3]','varchar(max)') 
      ,Pos4 = xDim.value('/x[4]','varchar(max)') 
      ,Pos5 = xDim.value('/x[5]','varchar(max)') 
      ,Pos6 = xDim.value('/x[6]','varchar(max)') 
      ,Pos7 = xDim.value('/x[7]','varchar(max)') 
      ,Pos8 = xDim.value('/x[8]','varchar(max)') 
      ,Pos9 = xDim.value('/x[9]','varchar(max)') 
    From (Select Cast('<x>' + Replace(@String,@Delimiter,'</x><x>')+'</x>' as XML) as xDim) A 
) 
--Select * from [dbo].[udf-Str-Parse-Row]('Dog,Cat,House,Car',',') 
--Select * from [dbo].[udf-Str-Parse-Row]('John Cappelletti',' ') 
1

はあなたがそれぞれの行でそれを分割するためのUDFを使用する必要がある

CREATE FUNCTION [DBO].[FN_SPLIT_STR_TO_COL] (@T AS VARCHAR(4000)) 
RETURNS 
@RESULT TABLE(VALUE VARCHAR(250)) 
AS 
BEGIN 
    SET @T= @T+';' 
     ;WITH MYCTE(START,[END]) AS(

    SELECT 1 AS START,CHARINDEX(';',@T,1) AS [END] 
    UNION ALL 
    SELECT [END]+1 AS START,CHARINDEX(';',@T,[END]+1)AS [END] 
    FROM MYCTE WHERE [END]<LEN(@T) 
    ) 
    INSERT INTO @RESULT 
    SELECT SUBSTRING(@T,START,[END]-START) NAME FROM MYCTE; 

     RETURN 
END 

は今、このTVFでCROSS APPLY

SELECT [CodeCombination],FN_RS.VALUE FROM TABLE1 
    CROSS APPLY 
(SELECT * FROM [DBO].[FN_SPLIT_STR_TO_COL] (User))   
    AS FN_RS 
0

あなたの[USER]列が一つだけセミコロンを持っている場合は必要ありません。 "分割文字列"機能は全くありません。あなたは、私が強くジェフMODENのDelimitedSplit8kまたはEirikur EirikssonのDelimitedSplit8K_LEADを使用することをお勧めし前のSQL Server 2016「スプリット文字列」機能を必要がある場合

-- Your Sample data 
DECLARE @table TABLE (CODE_COMBINATION varchar(30), [USER] varchar(100)); 
INSERT @table 
VALUES ('1111.111.11.0', 'KEN; JIMMY'), ('666.778.0.99', 'XKEN'), 
     ('888.66.77.99','LIM(JIM); JIMMY'); 

-- Solution using only CROSS APPLY 
SELECT CODE_COMBINATION, [USER] = LTRIM(s.s) 
FROM @table t 
CROSS APPLY (VALUES (CHARINDEX(';',t.[USER]))) d(d) 
CROSS APPLY 
(
    SELECT SUBSTRING(t.[USER], 1, ISNULL(NULLIF(d.d,0),1001)-1) 
    UNION ALL 
    SELECT SUBSTRING(t.[USER], d.d+1, 1000) 
    WHERE d.d > 0 
) s(s); 

:あなたはこのように適用CROSSを使用することができます。これらの両方とも、XMLベースのまたは再帰的なCTE「分割文字列」機能よりも優れています。

関連する問題