我有如下表格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函数的性能?
答案 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等价物(例如∓
),并保持原样。