从表中连接列值

时间:2014-07-03 10:50:44

标签: sql sql-server sql-server-2008

请考虑以下临时表:

DocID  Object  Field Value
--------------------------
 1      1       1        A
 2      1       1        B
 3      1       1        C
 4      1       2        A
 5      1       2        B
 6      2       1        F
 7      2       2        G
 8      2       2        H
 9      3       1        X
10      3       2        Y
11      3       3        Z
12      3       3        Z
13      3       3        Z

我想从查询中获得以下结果:

Object  Field  Values
---------------------
1       1      A;B;C
1       2      A;B
2       1      F
2       2      G;H
3       1      X
3       2      Y
3       3      Z

换句话说:

我想为每个values连接每个field的所有object

如果相同object的{​​{1}}相同,field存在相同的value(只有DocID不同),则结果应仅显示此重复值一次。如果没有此要求,结果将如下所示:

Object  Field  Values
---------------------
1       1      A;B;C
1       2      A;B
2       1      F
2       2      G;H
3       1      X
3       2      Y
3       3      Z;Z;Z  <------- repeating values

在任何脚本语言中,我都会将#temptable放在一个数组中并循环遍历它,但这次我必须在SQL(Server 2008)中完成此操作。

这甚至可能吗? SQL Server是否支持通过#temptable或任何其他结果集进行循环,如果是这样,您能否指出如何解决此问题?

非常感谢任何帮助。

1 个答案:

答案 0 :(得分:2)

您可以使用SQL Server的XML Extensions执行此操作:

SELECT  Object,
        Field,
        [Values] = STUFF((SELECT ';' + Value
                        FROM #TempTable AS T2
                        WHERE T2.Object = T.Object
                        AND T2.Field = T.Field
                        FOR XML PATH(''), TYPE
                        ).value('.', 'VARCHAR(MAX)'), 1, 1, '')

FROM    #temptable AS T
GROUP BY Object, Field;

有关此方法的工作原理的详细说明,请参阅this answer

修改

如果您只需要Values列中的唯一值,那么您只需将DISTINCT添加到子查询中:

SELECT  Object,
        Field,
        [Values] = STUFF((SELECT DISTINCT ';' + Value
                        FROM #TempTable AS T2
                        WHERE T2.Object = T.Object
                        AND T2.Field = T.Field
                        FOR XML PATH(''), TYPE
                        ).value('.', 'VARCHAR(MAX)'), 1, 1, '')

FROM    #temptable AS T
GROUP BY Object, Field;