2017-08-02 50 views
3

我有一個表,其中有兩列貸款no和counter_value。逗號分隔值在位的彙總

對每個貸款no都存有逗號分隔值列表。

declare @tbl table (loanno varchar(100) , counter_value varchar(200)) 

insert into @tbl 
values(‘pr0021’,‘1000,200,300,100,800,230’), 
(‘pr0021’,‘500,300,300,100,600,200’), 
(‘pr0021’,‘500,100,200,190,400,100’) 

我需要根據貸款數量和就地彙總(彙總)計數器值進行分組。 我需要如下的輸出。

loanno counter_value 
pr0021 2000,600,800,390,1800,530 
+3

不是最大的數據庫設計,但如果一致,我們可以使事情的工作。你在counter_values字段中有6個項目嗎? – Eli

+0

是的,每個項目總會有6個值。 – hieko

+0

我同意@Eli,這是一個可怕的設計,因爲它違反了1NF。由於您的設計,您必須在這裏跳過很多圈。如果這是正確的標準化,這將是非常簡單的。 –

回答

5

由於您對數據進行了非規範化處理,因此首先必須將其拆分爲多列,然後執行聚合,然後重新創建分隔列。有很多分離器在那裏,但這是我最喜歡的這種類型的東西。 http://www.sqlservercentral.com/articles/Tally+Table/72993/這個分離器的主要優點是它可以返回大多數其他分離器所不具備的每個值的位置。

利用這個分離器,你可以這樣做。

with AggregateData as 
(
    select t.loanno 
     , s.ItemNumber 
     , TotalValue = sum(convert(int, s.Item)) 
    from @tbl t 
    cross apply dbo.DelimitedSplit8K(t.counter_value, ',') s 
    group by t.loanno 
     , s.ItemNumber 
) 

select ad.loanno 
    , STUFF((select ',' + convert(varchar(10), ad2.TotalValue) 
     from AggregateData ad2 
     where ad2.loanno = ad.loanno 
     order by ad2.ItemNumber 
     FOR XML PATH('')), 1, 1, '') 
from AggregateData ad 
group by ad.loanno 
2

肖恩的將是我的第一選擇(+1)。

但是,如果有一個已知的(或固定的)數量的位置,考慮以下幾點:

Select A.loanno 
     ,NewAggr = concat(sum(Pos1),',',sum(Pos2),',',sum(Pos3),',',sum(Pos4),',',sum(Pos5),',',sum(Pos6)) 
From @tbl A 
Cross Apply (
       Select Pos1 = n.value('/x[1]','int') 
         ,Pos2 = n.value('/x[2]','int') 
         ,Pos3 = n.value('/x[3]','int') 
         ,Pos4 = n.value('/x[4]','int') 
         ,Pos5 = n.value('/x[5]','int') 
         ,Pos6 = n.value('/x[6]','int') 
        From (Select cast('<x>' + replace(A.counter_value,',','</x><x>')+'</x>' as xml) as n) X 
      ) B 
Group By A.loanno 

返回

loanno NewAggr 
pr0021 2000,600,800,390,1800,530 

如果它與可視化幫助,CROSS應用生成

enter image description here