2012-02-22 50 views
0

我這樣做:串聯並組多行

, cte_proc_code (accn,proc_code) as 
(SELECT accn_id, 
    (SELECT proc_code + ',' 
    FROM [XDataFullExtract].[dbo].[accn_billed_procedures] 
    FOR XML PATH('') 
    ) 
FROM [XDataFullExtract].[dbo].[accn_billed_procedures] 
group by accn_id) 

我的數據是這樣的:

accn_id,proc_code 
AA123, 1132 
AA123, 5234 
AA123, 4524 
BB123, 2345 
BB123, 4444 

,我想結果是:

accn_id,proc_code 
AA123, 1132, 5234, 4524 
BB123, 2345, 4444 

我的解決辦法但它的工作方式太慢了!

有沒有更快的方法來做到這一點?我認爲XML正在讓我失望。

+1

你能定義「太慢」嗎? 'dbo.accn_billed_procedures'中有多少行?有沒有涉及'accn_id'和'proc_code'的索引?你是否有理由不用WHERE子句拉動整個表?細節,細節,細節... – 2012-02-22 22:08:37

+4

[在Transact-SQL中連接行值](http://www.simple-talk.com/sql/t-sql-programming/concatenating-row-values-in-transact-sql /)涵蓋幾乎所有的技術。也許你應該嘗試一個,直到你達到你的表演預算。 – 2012-02-22 22:14:56

回答

1

這種方法涉及添加一個臨時列到你的表,但可以跑得更快:

-- table, with new varchar(max) column cncat added 
declare @t table(accn_id varchar(30), proc_code varchar(30), cncat varchar(max)); 
declare @concat varchar(max)=''; --staging variable 
  
insert into @t values 
('AA123','1132','') 
, ('AA123','5234','') 
, ('AA123','4524','') 
, ('BB123','2345','') 
, ('BB123','4444',''); 
  
-- update cncat 
with cte as (select *,r=row_number()over(partition by accn_id order by proc_code) from @t) 
update cte set @concat = cncat = case cte.r when 1 then '' else @concat end + ','+proc_code 
  
-- results 
select accn_id, cncat=stuff(max(cncat),1,1,'') 
from @t 
group by accn_id; 
  
-- clean up (optional) 
update @t set cncat=''; 
go 
1

在您提供它的查詢是不是「被放慢你失望的XML」。
您正在爲返回的每一行使用全部值構建逗號分隔的字符串。
您在子查詢中缺少where子句,應該將您的連接值過濾爲僅在外部查詢中使用當前行的行。