我在T-SQL中有一个表,目前只有一列,其中有一堆书名:
Book Title
------------------
Romeo and Juliet
Hamlet
All The King's Men
我要做的是添加第二列,称为“其他标题”,其中包含除了当前行中标题之外的所有其他标题的字符串,即
Book Title Other Titles
------------------ ----------------
Romeo and Juliet Hamlet, All The Kings Men
Hamlet R & J, All The King's Men
All The King's Men R&J, Hamlet
我知道我可能在T-SQL中使用STRING_AGG,但我似乎无法弄明白。有任何想法吗?
如果你的sql-server版本支持STRING_AGG
功能。
您可以尝试通过条件t2.[Book Title] <> t1.[Book Title]
进行自联接,然后使用STRING_AGG
函数,
CREATE TABLE T(
[Book Title] VARCHAR(50)
);
INSERT INTO T VALUES ('Romeo and Juliet');
INSERT INTO T VALUES ('Hamlet');
INSERT INTO T VALUES ('All The King''s Men');
SELECT t1.[Book Title],
STRING_AGG ( t2.[Book Title] , ',' ) 'Other Titles'
FROM T t1
INNER JOIN T t2 ON t2.[Book Title] <> t1.[Book Title]
group by t1.[Book Title]
我会使用相关的子查询来做到这一点:
select b.*,
(select string_agg(b2.title, ', ') within group (order by b2.title)
from books b2
where b2.title <> b.title
) as other_titles
from books b;
相关子查询可以更容易地保留表中可能包含的其他列。
说实话,表现并不是特别好。您可以考虑将所有内容聚合在一起然后删除标题:
select b.*,
stuff(replace(bb.titles, ', ' + b.title, ''), 1, 2, '') as other_titles
from books b cross join
(select ', ' + string_agg(b2.title, ', ') as titles
from books
) bb;
在replace()
上调用titles
通常比循环遍历整个表以重建每行的字符串具有更好的性能。