从T-SQL中的其他列派生列

时间:2018-09-15 22:10:51

标签: sql sql-server tsql sql-server-2017

到目前为止,我在T-SQL中有一个表格,书中只有一栏,里面有一堆书名:

    Book Title
------------------
Romeo and Juliet

Hamlet

All The King's Men

我想做的是添加第二列,称为“其他标题”,该列包含当前行标题中列中所有其他标题的字符串,即< / p>

 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,但是我似乎无法弄清楚。有任何想法吗?

2 个答案:

答案 0 :(得分:3)

如果您的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]

sqlfiddle

答案 1 :(得分:1)

我将使用相关子查询来做到这一点:

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通常比遍历整个表以重建每一行的字符串具有更好的性能。