我正在使用sql server 2014,我有一个这样的表(## tt_allresults)
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 :(得分:2)
不需要UDF,可以在CROSS APPLY和一点点XML的帮助下完成
您可以根据需要进行扩展或收缩。我留下9个位置来说明
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
<强>返回强>
Area Old Value New Value Function
FB1 0 50 Blah1 func
FB2 99 5 Blah2 func
FB1 50 55 Blah1 func
或2使用功能
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
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 APPLY(可以很容易地成为TVF)产生以下内容
答案 1 :(得分: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
- 我使用了一个tabled值函数来完成它,源是这个
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