SQL将多行合并为一行
我目前正在编写一个SQL脚本-包含一个业务术语和所有相关的同义词。它所做的是创建多行,因为有多个同义词也可以有多个值的其他列 我试图做的是为每个业务术语创建一行,并连接值,以分隔,这样我只为每个业务术语获得一个行项目 当前我的SQL脚本是:SQL将多行合并为一行,sql,sql-server,tsql,sql-server-2014,Sql,Sql Server,Tsql,Sql Server 2014,我目前正在编写一个SQL脚本-包含一个业务术语和所有相关的同义词。它所做的是创建多行,因为有多个同义词也可以有多个值的其他列 我试图做的是为每个业务术语创建一行,并连接值,以分隔,这样我只为每个业务术语获得一个行项目 当前我的SQL脚本是: SELECT dbo.TblBusinessTerm.BusinessTerm, dbo.TblBusinessTerm.BusinessTermLongDesc, dbo.TblBusinessTerm.DomainCatID, dbo.T
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开发人员?请使用STRING\u AGG函数。它将字段中的记录项组合在一起,并将它们设置在一个用指定分隔符分隔的记录中 详情如下:
您的查询很复杂,因此我将在这里发布示例数据以及如何以您想要的方式处理它。操作是字符串聚合和连接,在最新版本中有一个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列中包含所有相应的行。在最顶端编写with语句,不使用select。
然后按原样编写上层查询并进行更改
INNER JOIN dbo.TblBusinessSynonym ON dbo.TblBusinessTerm.BusinessTermID = dbo.TblBusinessSynonym.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
可能的重复可能需要使用CONCAT_WS表示分隔值,或使用CONCAT表示常规值。无法识别STRING_AGG。在MSSQL 2016之前不支持此函数。这里是这样的约定-查询很简单,我有过复杂,但是,我无法将表连接等方面的内容与我的内容相关联,因为这些内容仅在SQL server中开始,所以仍在尝试解决方法。我已设法运行脚本-谢谢-但现在SYNS根本不显示为列标题。已重新发布ammeded代码我已添加完整查询。。。在syn中使用左连接可能是查询中更好的方式谢谢。仍然不喜欢类似的dbo.TblTableOwner.TableOwnerName,syn.syns有一个问题syn.sys-说不能使用多部分标识符syn.syns上是否有输入错误?它应该是syn.synsNo类型,在dbo.TblBusinessTerm.BusinessTermID=syn.BusinessTermID上的dbo.syn上也有问题-表示dbo.syn-对象名称无效。它似乎并没有在with语句中提取SYN并将其传递到查询的其余部分
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