1

我有以下数据使用FOR XML Path的sql server中的字符串连接问题。

UniqueID ID data 
1  1 a 
2  1 2 
3  1 b 
4  1 1 
5  2 d 
6  2 3 
7  2 r 

预期的输出是

ID ConcatData 
1 a,-,-,b,- 
2 d,-,-,-,r 

我们要做的是什么,数字charecters的数量必须与许多破折号(替换“ - ” ),然后我们需要合并各自ID的数据。

我使用下面的查询到目前为止

declare @t table(UniqueID int identity(1,1), ID int, data varchar(10)) 
insert into @t select 1, 'a' union all select 1, '2' union all select 1, 'b' 
union all select 1, '1' union all select 2, 'd' union all select 2, '3' 
union all select 2, 'r' 

select * from @t 

;with cte1 as 
(  
    select 
     UniqueId 
     , id 
     , data 
     , case when isnumeric(data) = 1 then cast(data as int) end Level 
     from @t  
    union all  
    select 
     UniqueId 
     , id 
     , CAST('-' as varchar(10)) 
     , Level - 1  
    from cte1  
    where Level > 0) 
,cte2 as 
(
select id, GroupID = Dense_Rank() Over(Order by id),data, DataOrder = ROW_NUMBER() over(order by UniqueID, Level) 
from cte1 
where Level is null or data = '-' 
) 

SELECT 
ID 
, (select data + ',' 
from cte2 t2 
where t2.GroupID = t1.GroupID 
for XML path('') 
) as ConcatData 
from cte2 t1 
group by t1.ID ,t1.GroupID 

但输出

ID ConcatData 
1 a,b,-,-,-, 
2 d,r,-,-,-, 

这是我不能给短线的位置 - 在字符之间(“”)。

请帮

回答

0

试试这个:

;with cte1 as 
(
select 
UniqueId 
, id 
, data 
,case when isnumeric(data) = 1 
    THEN replicate(',-',data) 
    ELSE ',' + data end as string 
from @t 
) 

select 
id 
,LTRIM(STUFF(
    (
    SELECT 
     ' ' + t2.String 
    FROM Cte1 t2 
    WHERE t2.id = t1.id 
    FOR XML PATH('') 
    ), 2, 1, '' 
)) As concatenated_string 
from cte1 t1 group by t1.ID ,t1.ID 

作品为样本数据波夫,可能会比使用游标

+0

谢谢你学习关于复制的新东西。我同意,你的建议更好。谢谢:) – Pankaj 2011-06-16 11:06:34

+0

+1复制 – Pankaj 2011-06-16 11:07:50

0

以下是表格制作

Create table #temp 
(
    IDUnique int Identity(1,1), 
    ID int, 
    data varchar(100) 
) 

以下是你所建议的记录。

Insert into #temp(ID, data) Values(1, 'a') 
Insert into #temp(ID, data) Values(1, '2') 
Insert into #temp(ID, data) Values(1, 'b') 
Insert into #temp(ID, data) Values(1, '1') 
Insert into #temp(ID, data) Values(2, 'd') 
Insert into #temp(ID, data) Values(2, '3') 
Insert into #temp(ID, data) Values(2, 'r') 

enter image description here

以下是光标实现

declare @IDUnique int 
declare @ID int 
declare @data varchar(100) 
declare @Latest int 
declare @Previous int 
declare @Row int 

set @Latest = 1 
set @Previous = 1 

Create Table #temp1 
(
    ID int, 
    data varchar(100) 
) 

--SELECT Row_Number() Over(Order by IDUnique) Row, IDUnique, ID, data From #temp 


DECLARE @getAccountID CURSOR SET @getAccountID = CURSOR FOR SELECT Row_Number() Over(Order by IDUnique) Row, IDUnique, ID, data From #temp 
OPEN @getAccountID 
FETCH NEXT FROM @getAccountID INTO @Row, @IDUnique, @ID, @data 
WHILE @@FETCH_STATUS = 0 
BEGIN 
    IF(@Row = 1) 
    Begin 
     Set @Previous = @ID 
     Set @Latest = @ID 
     Insert into #temp1(ID, data)values(@Previous, @data) 
    End 
    Else If (@Previous <> @ID) 
    Begin 
     Set @Previous = @ID 
     Set @Latest = @ID 
     Insert into #temp1(ID, data)values(@Previous, @data) 
    End 
    Else 
    Begin 
     Declare @number int 
     if(ISNUMERIC(@data) = 1) 
     Begin 
      Set @number = Convert(int , @data) 
      While(@number <> 0) 
      Begin 
       Update #temp1 Set Data = Data + ',-' Where ID = @ID 
       Set @number = @number - 1 
      End 
     End 
     Else  
     begin 
      Update #temp1 Set Data = Data + ',' + @data Where ID = @ID 
     End 
    End 

    FETCH NEXT FROM @getAccountID INTO @Row, @IDUnique, @ID, @data 
END 
CLOSE @getAccountID 
DEALLOCATE @getAccountID 

Select * from #temp1 
Select * from #temp 
Drop Table #temp 

这里是最终的结果集

enter image description here

+0

你正在做筛选的数字和其他然后数值更快一点。这就是输出不正确的原因。为了顺序移动,我认为你应该使用光标移动。 – Pankaj 2011-06-16 09:49:41