CONCAT(专栏)OVER(PARTITION BY ...)?分组连接行而不对结果本身进行分组

Zan*_*ien 10 sql t-sql sql-server sql-server-2008 string-aggregation

我需要一种方法来在一种窗口函数中对所有行(每组)进行串联,就像你可以做的那样COUNT(*) OVER(PARTITION BY...),每个组的所有行的聚合计数将在每个特定的组中重复.我需要类似的东西,但是每个组中重复的每个组的所有值的字符串连接.

这是一些示例数据和我想要的结果,以更好地说明我的问题:

grp  |  val
------------
1    |  a
1    |  b
1    |  c
1    |  d
2    |  x
2    |  y
2    |  z
Run Code Online (Sandbox Code Playgroud)

这就是我需要的(期望的结果):

grp  |   val  |  groupcnct
---------------------------------
1    |   a    |  abcd
1    |   b    |  abcd
1    |   c    |  abcd
1    |   d    |  abcd
2    |   x    |  xyz
2    |   y    |  xyz
2    |   z    |  xyz
Run Code Online (Sandbox Code Playgroud)

以下是此问题的棘手部分:

我的特殊情况使我无法两次引用同一个表(我实际上是在递归CTE中执行此操作,因此我无法对CTE进行自联接,否则会引发错误).

我完全清楚可以做一些事情:

SELECT      a.*, b.groupcnct
FROM        tbl a
CROSS APPLY (
            SELECT STUFF((
                        SELECT '' + aa.val 
                        FROM   tbl aa
                        WHERE  aa.grp = a.grp
                        FOR XML PATH('')
                   ), 1, 0, '') AS groupcnct
            ) b
Run Code Online (Sandbox Code Playgroud)

但正如您所看到的,这在查询中引用了tbl 两次.

我只能引用tbl 一次,因此我想知道是否可以窗口化组连接(我对TSQL有点新,因为我来自MySQL背景,所以不确定是否可以这样做).


创建表:

CREATE TABLE tbl
    (grp int, val varchar(1));

INSERT INTO tbl
    (grp, val)
VALUES
    (1, 'a'),
    (1, 'b'),
    (1, 'c'),
    (1, 'd'),
    (2, 'x'),
    (2, 'y'),
    (2, 'z');
Run Code Online (Sandbox Code Playgroud)

Mic*_*uen 1

我尝试使用纯 CTE 方法:Which is the best way to form the string value using columns from a Table with rows has same ID? 认为这样更快

但基准测试告诉我们,最好使用子查询(或CROSS APPLY)结果,因为XML PATH它们更快:Which is the best way to form the string value using column from a Table with rows has same ID?