将以前的所有列合并到当前列

mum43rcc  于 2021-07-26  发布在  Java
关注(0)|答案(1)|浏览(404)

我有一个名为terms的表,我使用的是sql server 2014

  1. termID termname
  2. 1 term1
  3. 2 term2
  4. 3 term3
  5. 4 term4

我想要这样的结果

  1. termID termname
  2. 1 term1
  3. 2 term1 and term2
  4. 3 term1 and term2 and term3
  5. 4 term1 and term2 and term3 and term4

我是用 LAG() ,但我只能得到前一个值。我需要得到前面所有列的值。

  1. select termid, CASE WHEN ISNULL(prev_word,'')<>'' THEN prev_word+' and '+ termname ELSE termname END
  2. from (
  3. select termID,
  4. lag(termname) over (order by termID) as prev_word,
  5. termname
  6. from terms
  7. ) as t
mkh04yzy

mkh04yzy1#

一些数据库(如postgres)支持 string_agg() 作为一个窗口函数,您可以将其编写为:

  1. select
  2. temid,
  3. string_agg(termname, ' and ') over(order by termid) termname
  4. from terms

... 不幸的是,SQLServer还不支持这种语法。
另一种方法是递归查询。我不会这么想 termid 总是从 1 并且总是不带间隙地递增,因此首先用 row_number() ,然后迭代遍历数据集,一步一步累积字符串:

  1. with
  2. data as (
  3. select t.*, row_number() over(order by termid) rn from terms t
  4. ),
  5. cte as (
  6. select termid, cast(termname as varchar(max)) termname, rn
  7. from data
  8. where rn = 1
  9. union all
  10. select d.termid, c.termname + ' and ' + d.termname, d.rn
  11. from cte c
  12. inner join data d on d.rn = c.rn + 1
  13. )
  14. select termid, termname from cte order by termid

如果列表中的值超过100个,则需要添加 option (maxrecursion 0) 在查询的最后(否则将达到100次迭代的默认限制)。
db小提琴演示:

  1. termid | termname
  2. -----: | :----------------------------------
  3. 1 | term1
  4. 2 | term1 and term2
  5. 3 | term1 and term2 and term3
  6. 4 | term1 and term2 and term3 and term4
展开查看全部

相关问题