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