【问题标题】:SQL to combine multiple rows into a single rowSQL将多行组合成一行
【发布时间】:2018-04-17 05:19:14
【问题描述】:

我目前正在编写一个 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

但是现在我如何在上述所有链接的查询中使用它?

想用来自syn的结果替换dbo.TblBusinessSynonym.Synonym

有可以提供帮助的 SQL 2014 开发人员吗?

【问题讨论】:

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


【解决方案1】:

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

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

【讨论】:

  • 设法让脚本运行 - 谢谢 - 但现在 SYNS 根本不显示为列标题。已转发修改代码
  • 我已经添加了完整的查询... syn 中的 LEFT JOIN 可能是查询中更好的方法
  • 谢谢。仍然不喜欢 dbo.TblTableOwner.TableOwnerName, syn.syns 之类的问题 syn.sys - 说无法绑定多部分标识符
  • syn.syns 上有错字吗?它应该是 syn.syns
  • 无类型,dbo.syn ON dbo.TblBusinessTerm.BusinessTermID = syn.BusinessTermID 也有问题 - dbo.syn 说 - 对象名称无效。它似乎没有在 with 语句中提取 SYN 并将其带到其余的查询中
【解决方案2】:

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

详情在这里: https://docs.microsoft.com/en-us/sql/t-sql/functions/string-agg-transact-sql?view=sql-server-2017

【讨论】:

【解决方案3】:

您的查询很复杂,所以我将在这里发布示例数据以及如何以您想要的方式处理它。该操作是带有连接的字符串聚合,在最新版本中有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 列中的所有对应行。

【讨论】:

  • 同意 - 简单的查询我已经过于复杂,但我无法将你所拥有的与我在表连接等方面所拥有的相关联 - 仅在 SQL Server 中开始,所以仍在尝试找到我的路。
猜你喜欢
  • 1970-01-01
  • 2013-12-31
  • 2019-03-15
  • 2017-10-03
  • 2023-03-09
  • 1970-01-01
  • 1970-01-01
  • 2021-10-21
  • 2014-03-08
相关资源
最近更新 更多