替代sql server中的stuff函数

时间:2015-01-24 15:30:21

标签: sql sql-server group-by sql-server-2012

我有如下表格Tab1(我的实际表格最多有20,000行

a     b      c    statecode
-------------------------------------------
A1   abc   def    FL          
B1   abc   def    AZ
C1   abc   def    MI
D1   abc   def    CO
E1   abc   def    IL
F1   abc   def    CA

这是我想要做的:对于列b和c的给定组合,如果存在多行,那么我想连接逗号分隔的“a - statecode”。

我需要一个像下面这样的结果......

a     b      c    statecode   output
-------------------------------------------
A1   abc   def      FL          A1-FL,B1-AZ,C1-MI,D1-CO,E1-IL,F1-CA

我尝试了什么: 我试过这个

的sql stuff函数
SELECT a, b,c,
  STUFF((SELECT  distinct ', '+ t1.a +'-'+ t1.statecode
             FROM Tab1 t1
             where  t2.b = t1.a
             and    t2.c= t1.c 
             FOR XML PATH('')), 1, 1,'') AS output
from Tab1 t2;

这适用于相对较小的表,我的实际表有20,000行和15列,我必须检查10列组合的相等性(如本例中的b,c还有8列)。

有没有更好的方法在sql中执行此操作?或提高stuff函数的性能?

1 个答案:

答案 0 :(得分:1)

这里的问题不是stuff()功能。它是子查询和XML处理。

在SQL Server中确实没有替代方案。我的意思是,还有另外两种方法可以进行聚合字符串连接:编写自己的UDF,或者,如果只有少量值,则使用row_number()和字符串连接。

在走这条路线之前,请尝试优化您的查询。首先要做的是在tab1(a, c)上创建一个索引。

注意:最好使用显式XML标记来编写它。语法非常相似:

SELECT a, b,c,
  STUFF((SELECT  distinct ', '+ t1.a +'-'+ t1.statecode
             FROM Tab1 t1
             where  t2.b = t1.a and
                    t2.c= t1.c 
             FOR XML PATH('concat'), Type
         ).Value('/concat[1]', 'varchar(max)'), 1, 1,'') AS ACCEPTED_SYMBOLS
from Tab1 t2;

这样做是在XML中创建字符串连接,然后将其从XML转换回字符串。好处是,&<>字符不会转换为XML等价物(例如&mp;),并保持原样。