简体   繁体   English

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

[英]Deriving columns from other column in T-SQL

I have a table in T-SQL in books with just one column so far, which has a bunch of book titles: 我在T-SQL的书中有一张表,到目前为止只有一列,其中有一堆书名:

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

Hamlet

All The King's Men

What I am trying to do is add a second column, called "Other Titles" that contains a string of all the other titles in the column except for the title in the current row, ie 我想做的是添加第二列,称为“其他标题”,其中包含该列中当前行标题以外的所有其他标题的字符串,即

 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

I know I have to probably use STRING_AGG in T-SQL for this, but I just can't seem to figure it out. 我知道我可能必须在T-SQL中使用STRING_AGG,但是我似乎无法弄清楚。 Any ideas? 有任何想法吗?

If your sql-server version support STRING_AGG function. 如果您的sql-server版本支持STRING_AGG函数。

You can try to do self-join by condition t2.[Book Title] <> t1.[Book Title] then use STRING_AGG function, 您可以尝试根据条件t2.[Book Title] <> t1.[Book Title]进行自我加入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 sqlfiddle

I would do this using a correlated subquery: 我将使用相关的子查询来做到这一点:

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;

A correlated subquery makes it easier to keep other columns that you might have in your table. 相关子查询使您可以更轻松地保留表中可能包含的其他列。

To be honest, though, the performance is not going to be particularly good. 不过,老实说,性能不会特别好。 You might consider aggregating everything together and then removing your title: 您可以考虑将所有内容汇总在一起,然后删除标题:

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;

Calling replace() on titles would typically have better performance than looping through the entire table to reconstruct the string for each row. 与在整个表中循环以为每一行重建字符串相比,在titles上调用replace()通常具有更好的性能。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM