SQL将多行合并为一行

时间:2018-04-17 05:19:14

标签: sql sql-server tsql sql-server-2014

我目前正在编写一个SQL脚本 - 需要一个商业术语,以及所有相关的同义词。它的作用是创建多行(因为有多个同义词(也可以有其他列也可以是多个值。

我要做的是为每个业务术语创建一行,并连接值(分隔),以便我只为每个业务术语获得一个行项目。

目前我的SQL脚本是:

SELECT dbo.TblBusinessTerm.BusinessTerm, dbo.TblBusinessTerm.BusinessTermLongDesc, 
       dbo.TblBusinessTerm.DomainCatID, dbo.TblSystem.SystemName, 
       dbo.TblDomainCat.DataSteward, dbo.TblDomainCat.DomainCatName, 
       dbo.TblField.GoldenSource, dbo.TblField.GTS_table, 
       dbo.TblTableOwner.TableOwnerName, dbo.TblBusinessSynonym.Synonym 
FROM   dbo.TblTableOwner INNER JOIN
       dbo.TblBusinessTerm INNER JOIN
       dbo.TblBusinessSynonym ON dbo.TblBusinessTerm.BusinessTermID = dbo.TblBusinessSynonym.BusinessTermID INNER JOIN
       dbo.TblField ON dbo.TblBusinessTerm.BusinessTermID = dbo.TblField.BusinessTermID INNER JOIN
       dbo.TblSystem INNER JOIN
       dbo.TblTable ON dbo.TblSystem.SystemID = dbo.TblTable.SystemID ON dbo.TblField.TableID = dbo.TblTable.TableID INNER JOIN
       dbo.TblDomainCat ON dbo.TblBusinessTerm.DomainCatID = dbo.TblDomainCat.DomainCatID ON dbo.TblTableOwner.TableOwnerID = dbo.TblDomainCat.DataSteward

是否有一种简单的方法可以将性能考虑在内 - 这是SQL新手。

谢谢

我设法创建了一个with语句,现在连接我的行:

With syn as (
    select [BusinessTermID],
           syns = STUFF((SELECT  ', ' + dbo.TblBusinessSynonym.Synonym
                         FROM   dbo.TblBusinessSynonym
                         WHERE  [BusinessTermID] = x.[BusinessTermID]
                             AND    dbo.TblBusinessSynonym.Synonym <> ''
                         FOR XML PATH ('')),1,2,'')
    FROM dbo.TblBusinessSynonym AS x
    GROUP BY [BusinessTermID]
)
select * from syn

但是现在我怎样才能在上面的查询中使用它来处理所有内容?

希望将dbo.TblBusinessSynonym.Synonym替换为syn

的结果

任何可以提供帮助的SQL 2014开发人员?

3 个答案:

答案 0 :(得分:1)

请使用STRING_AGG功能。它将字段中的记录项组合在一起,并将它们设置在一个用指定分隔符分隔的记录中。

详细信息如下: https://docs.microsoft.com/en-us/sql/t-sql/functions/string-agg-transact-sql?view=sql-server-2017

答案 1 :(得分:1)

在最顶部写下语句,不要选择。 然后按原样编写您的上层查询并更改

INNER JOIN dbo.TblBusinessSynonym ON dbo.TblBusinessTerm.BusinessTermID = dbo.TblBusinessSynonym.BusinessTermID

INNER JOIN syn ON syn.BusinessTermID = dbo.TblBusinessTerm.BusinessTermID

就是这样

With syn as (
    select [BusinessTermID],
           syns = STUFF((SELECT  ', ' + dbo.TblBusinessSynonym.Synonym
                         FROM   dbo.TblBusinessSynonym
                         WHERE  [BusinessTermID] = x.[BusinessTermID]
                             AND    dbo.TblBusinessSynonym.Synonym <> ''
                         FOR XML PATH ('')),1,2,'')
    FROM dbo.TblBusinessSynonym AS x
    GROUP BY [BusinessTermID]
)

SELECT dbo.TblBusinessTerm.BusinessTerm, 
       dbo.TblBusinessTerm.BusinessTermLongDesc, 
       dbo.TblBusinessTerm.DomainCatID, dbo.TblSystem.SystemName, 
       dbo.TblDomainCat.DataSteward, dbo.TblDomainCat.DomainCatName, 
       dbo.TblField.GoldenSource, dbo.TblField.GTS_table, 
       dbo.TblTableOwner.TableOwnerName, syn.syns 
FROM   dbo.TblTableOwner INNER JOIN
       dbo.TblBusinessTerm INNER JOIN
       syn ON dbo.TblBusinessTerm.BusinessTermID = syn.BusinessTermID INNER JOIN
       dbo.TblField ON dbo.TblBusinessTerm.BusinessTermID = dbo.TblField.BusinessTermID INNER JOIN
       dbo.TblSystem INNER JOIN
       dbo.TblTable ON dbo.TblSystem.SystemID = dbo.TblTable.SystemID ON   dbo.TblField.TableID = dbo.TblTable.TableID INNER JOIN
       dbo.TblDomainCat ON dbo.TblBusinessTerm.DomainCatID = dbo.TblDomainCat.DomainCatID ON dbo.TblTableOwner.TableOwnerID = dbo.TblDomainCat.DataSteward

答案 2 :(得分:0)

您的查询很复杂,因此我将在此处发布示例数据以及如何以您想要的方式处理它。该操作是带有串联的字符串聚合,在最新版本中有string_agg函数,它为我们工作。但是,由于您无法使用此功能,因此可采用以下方法:

select * into #tt
from (values (1, '1'),(1, '2'),(2, '1'),(2, '2')) A(id, someStr) 

select id, (select someStr + ',' from #tt where id = [t].id for xml path('')) [grouped]
from #tt [t] group by id

Id之上的查询分组,并在someStr列中隐藏所有相应的行。