2017-01-13 1 views
1

SQL의 열 및 피벗에 문자열을 분할 나는 (이 같은 테이블 (## tt_allresults가)내가 SQL 서버 2014을 사용하고

ID  |  Area  |  Event                   | 
1  |  FB1   | Dev_Chg, Old Value: 0, New Value: 50, Workstation: Blah1, Function: Blah1 func  | 
1  |  FB2   | Dev_Chg, Old Value: 99, New Value: 5, Workstation: Blah2, Function: Blah2 func  |  
1  |  FB1   | Dev_Chg, Old Value: 50, New Value: 55, Workstation: Blah1, Function: Blah1 func  | 

내가 이렇게 같은 테이블에서 싶습니다 예상 출력이)

Area | Old Value |  New Value |  Function  | 
FB1  | 0   |  50   | Blah1 func   | 
FB2  | 99   |  5   | Blah2 func   | 
FB1  | 50   |  55   | Blah1 func   | 

이 내가 지금까지 나는 다음과 같은 결과를 얻을

Declare @id int 
WHILE EXISTS(SELECT * FROM ##tt_allresults) 
BEGIN 
Select Top 1 @id = Id from ##tt_allresults 

-- Do the work -- 
Declare @area nvarchar(100) 
set @area = (Select Area from ##tt_allresults where id = @id) 

Insert into ##tt_changedetails 
select @area, * from fnsplit((Select [event] from ##tt_allresults where id = @id),',') 

-- Scrap the ID and Move On -- 
Delete ##tt_allresults where ID = @id 
END 


select * from ##tt_changedetails 

을 시도한 것입니다

Area |  ChangeDetails  | 
FB1  | Dev_Chg     | 
FB1  | Old value :0   | 
FB1  | New Value :50   | 
FB1  | Workstation :blah1  | 
FB1  | Function :blah1 func | 
FB2  | Dev_Chg     | 
FB2  | Old value :99   | 
FB2  | New Value :5   | 
FB2  | Workstation :blah2  | 
FB2  | Function :blah2 func | 
FB1  | Dev_Chg     | 
FB1  | Old value :50   | 
FB1  | New Value :55   | 
FB1  | Workstation :blah1  | 
FB1  | Function :blah1 func | 

어떻게 초기 테이블을 분할하고 분할 기준으로 피벗합니까? 다음 결과를보고 싶습니다.

FB1  | 0   |  50   | Blah1 func   | 
FB2  | 99   |  5   | Blah2 func   | 
FB1  | 50   |  55   | Blah1 func   | 
+0

다음 (쉽게 TVF 될 수있는) 적용 생산 @Chanukya - 질문을 업데이트했습니다. 추가 질문이 있으시면 언제든지 문의하십시오. – Abe

+0

원하는 결과는 무엇입니까? – iamdave

+0

@iamdave - 내 질문에 예상되는 출력 테이블. – Abe

답변

2

필요가 없습니다를 완료하기 위해 상정 반환 함수를 사용 XML

필요에 따라 확장하거나 축소 할 수 있습니다. 나는 기능이없는

1)

을 설명

Declare @YourTable table (ID int,Area varchar(25),Event varchar(500)) 
Insert Into @YourTable values 
(1,'FB1','Dev_Chg, Old Value: 0, New Value: 50, Workstation: Blah1, Function: Blah1 func'), 
(1,'FB2','Dev_Chg, Old Value: 99, New Value: 5, Workstation: Blah2, Function: Blah2 func'), 
(1,'FB1','Dev_Chg, Old Value: 50, New Value: 55, Workstation: Blah1, Function: Blah1 func') 

Select A.Area 
     ,[Old Value] = Substring(Pos2,CharIndex(':',Pos2)+1,Len(Pos2)) 
     ,[New Value] = Substring(Pos3,CharIndex(':',Pos3)+1,Len(Pos3)) 
     ,[Function] = Substring(Pos5,CharIndex(':',Pos5)+1,Len(Pos5)) 
From @YourTable A 
Cross Apply (
       Select Pos1 = ltrim(rtrim(xDim.value('/x[1]','varchar(max)'))) 
         ,Pos2 = ltrim(rtrim(xDim.value('/x[2]','varchar(max)'))) 
         ,Pos3 = ltrim(rtrim(xDim.value('/x[3]','varchar(max)'))) 
         ,Pos4 = ltrim(rtrim(xDim.value('/x[4]','varchar(max)'))) 
         ,Pos5 = ltrim(rtrim(xDim.value('/x[5]','varchar(max)'))) 
         ,Pos6 = ltrim(rtrim(xDim.value('/x[6]','varchar(max)'))) 
         ,Pos7 = ltrim(rtrim(xDim.value('/x[7]','varchar(max)'))) 
         ,Pos8 = ltrim(rtrim(xDim.value('/x[8]','varchar(max)'))) 
         ,Pos9 = ltrim(rtrim(xDim.value('/x[9]','varchar(max)'))) 
       From (Select Cast('<x>' + replace((Select A.Event as [*] For XML Path('')),',','</x><x>')+'</x>' as xml) as xDim) as A 
     ) B 

반환 기능

Select A.Area 
     ,[Old Value] = Substring(Pos2,CharIndex(':',Pos2)+1,Len(Pos2)) 
     ,[New Value] = Substring(Pos3,CharIndex(':',Pos3)+1,Len(Pos3)) 
     ,[Function] = Substring(Pos5,CharIndex(':',Pos5)+1,Len(Pos5)) 
From @YourTable A 
Cross Apply [dbo].[udf-Str-Parse-Row](A.Event,',') B 

Area Old Value New Value Function 
FB1  0   50   Blah1 func 
FB2  99   5   Blah2 func 
FB1  50   55   Blah1 func 

또는 제 2 9 개 포지션을 왼쪽 0


UDF는


는 시각화에 도움이된다면

ALTER FUNCTION [dbo].[udf-Str-Parse-Row] (@String varchar(max),@Delimiter varchar(10)) 
Returns Table 
As 
Return (
    Select Pos1 = ltrim(rtrim(xDim.value('/x[1]','varchar(max)'))) 
      ,Pos2 = ltrim(rtrim(xDim.value('/x[2]','varchar(max)'))) 
      ,Pos3 = ltrim(rtrim(xDim.value('/x[3]','varchar(max)'))) 
      ,Pos4 = ltrim(rtrim(xDim.value('/x[4]','varchar(max)'))) 
      ,Pos5 = ltrim(rtrim(xDim.value('/x[5]','varchar(max)'))) 
      ,Pos6 = ltrim(rtrim(xDim.value('/x[6]','varchar(max)'))) 
      ,Pos7 = ltrim(rtrim(xDim.value('/x[7]','varchar(max)'))) 
      ,Pos8 = ltrim(rtrim(xDim.value('/x[8]','varchar(max)'))) 
      ,Pos9 = ltrim(rtrim(xDim.value('/x[9]','varchar(max)'))) 
    From (Select Cast('<x>' + replace((Select @String as [*] For XML Path('')),@Delimiter,'</x><x>')+'</x>' as xml) as xDim) as A 
) 
--Select * from [dbo].[udf-Str-Parse-Row]('Dog,Cat,House,Car',',') 
--Select * from [dbo].[udf-Str-Parse-Row]('John <test> Cappelletti',' ') 
를 필요한 경우 CROSS는

enter image description here

+0

감사합니다 위의 솔루션 작동합니다. – Abe

+0

@Abe 행복하게 도와주었습니다. –

0

여기가 올바른 검색어입니다. 도움이 되길 바랍니다.

  declare @str varchar(1000) 

     declare @temp as table (id int , area varchar(10) , [event] varchar(100)) 

     insert into @temp (id,area,[event]) values (1,'FB1','Dev_Chg, Old Value: 0, New Value: 50, Workstation: Blah1, Function: Blah1 func') 
     insert into @temp (id,area,[event]) values (1,'FB2','Dev_Chg, Old Value: 99, New Value: 5, Workstation: Blah2, Function: Blah2 func') 
     insert into @temp (id,area,[event]) values (1,'FB1','Dev_Chg, Old Value: 50, New Value: 55, Workstation: Blah1, Function: Blah1 func') 

     set @str ='Dev_Chg, Old Value: 0, New Value: 50, Workstation: Blah1, Function: Blah1 func' 



     select * from (
     select area, RTRIM(LTRIM( SUBSTRING(String,0 , CHARINDEX (':',String))))as theader , SUBSTRING(String, CHARINDEX (':',String)+1,15) as tvalue from (
     select * from 
     @temp cross apply 
     dbo.ufn_CSVToTable ([event]) 
     ) b 
     where b.String!='Dev_Chg' 

     ) 
     as final 
     pivot ( max (tvalue) for theader in ([Old Value] , [New Value],[Workstation],[Function]) 
     ) as pvt 

- 난 모든 CROSS의 도움을 적용하고 약간 함께 할 수있는, 소스가 UDF이

 ALTER FUNCTION [dbo].[ufn_CSVToTable] (@StringInput VARCHAR(8000)) 
     RETURNS @OutputTable TABLE ([String] nVARCHAR(1000)) 
     AS 
     BEGIN 

      DECLARE @String nVARCHAR(1000) 

      WHILE LEN(@StringInput) > 0 
      BEGIN 
       SET @String  = LEFT(@StringInput, 
             ISNULL(NULLIF(CHARINDEX(',', @StringInput) - 1, -1), 
             LEN(@StringInput))) 
       SET @StringInput = SUBSTRING(@StringInput, 
              ISNULL(NULLIF(CHARINDEX(',', @StringInput), 0), 
              LEN(@StringInput)) + 1, LEN(@StringInput)) 

       INSERT INTO @OutputTable ([String]) 
       VALUES (@String) 
      END 

      RETURN 
     END 
+0

답변에 '문자열'이 무엇입니까? – Abe

+0

@Abe 이것은 내가 적용한 사용자 정의 함수의 출력입니다. 비록 당신이 제시 한 현재의 데이터로 우리는 당신이 정확하게 피벗 할 수 없다는 문제가 있다고 언급했지만, 3 대신에 2 개의 레코드를 보여줍니다. 약간의 재 작업이 필요하지만 거의 모든 질문에 대한 답이 쿼리에 포함됩니다. 나는 이것이 당신에게 도움이되기를 바랍니다. –

+0

나는 귀하의 기능을 실행했으며 귀하의 스크립트를 실행할 수 없습니다. '문자열'이 문제입니다. 나는 뭔가를 놓친다. – Abe