对按公共键分组的 n 行数据使用 string_agg()

Col*_*in9 2 sql sql-server common-table-expression recursive-cte

我想string_agg(column_name,',')在 SQL 结果集中的列中使用一些 ID。我将按单个键进行分组,但也想确保每个分组集都会导致 n 行被输入到函数string_agg(column_name,',')

例子:

create table #temp (first_name varchar(20), data_id char(3))
insert into #temp (first_name, data_id) values('jeff', 'XX1')
insert into #temp (first_name, data_id) values('jeff', 'X23')
insert into #temp (first_name, data_id) values('jeff', 'X87')
insert into #temp (first_name, data_id) values('jeff', 'X09')
insert into #temp (first_name, data_id) values('jeff', 'X15')

insert into #temp (first_name, data_id) values('bob', 'X76')
insert into #temp (first_name, data_id) values('bob', 'X17')
insert into #temp (first_name, data_id) values('bob', 'X98')
insert into #temp (first_name, data_id) values('bob', 'X99')

select * from #temp

first_name  data_id
      jeff      XX1
      jeff      X23
      jeff      X87
      jeff      X09
      jeff      X15
       bob      X76
       bob      X17
       bob      X98
       bob      X99
Run Code Online (Sandbox Code Playgroud)

我试图创建的理想结果是,每组聚合的 n = 3 行字符串如下。如果该特定first_name键剩余 <3 行,则将剩余的放入该列中。

我正在尝试使用递归 CTE,但无法完全理解它

first_name        data_id
      jeff    XX1,X23,X87
      jeff        X09,X15
       bob    X76,X17,X98
       bob            X99
Run Code Online (Sandbox Code Playgroud)

Dan*_*lor 5

select  first_name
       ,string_agg(data_id, ',') as data_id
from    (
        select  *
                ,(row_number() over(partition by first_name order by data_id)-1)/3 as grp
        from     #temp
        ) t
group by first_name, grp
order by first_name
Run Code Online (Sandbox Code Playgroud)
数据ID
鲍勃 X17,X76,X98
鲍勃 X99
杰夫 X09,X15,X23
杰夫 X87,XX1

小提琴