Sql 将名称之间的链接列表合并为一列
我目前有两个表用于存储实体之间的关系,如下所示: 实体\u表:包含实体的名称和类型(主实体或辅助实体)Sql 将名称之间的链接列表合并为一列,sql,sql-server,tsql,group-by,coalesce,Sql,Sql Server,Tsql,Group By,Coalesce,我目前有两个表用于存储实体之间的关系,如下所示: 实体\u表:包含实体的名称和类型(主实体或辅助实体) ENTITY_ID | ENTITY_NAME | ENTITY_TYPE ----------------------------------------- 1 | 'entity_1' | 'master' 2 | 'entity_2' | 'secondary' 3 | 'entity_3' | 'se
ENTITY_ID | ENTITY_NAME | ENTITY_TYPE
-----------------------------------------
1 | 'entity_1' | 'master'
2 | 'entity_2' | 'secondary'
3 | 'entity_3' | 'secondary'
...
链接表:包含实体之间的关系信息
MASTER_ID | SECONDARY_ID
--------------------------
1 | 2
1 | 3
...
其他信息:
- 大约有5000个实体,每个实体可以有几个链接,有些没有链接 <>这些表是由外部C++代码< /LI>使用的
ENTITY_ID | ENTITY_TYPE | ENTITY_LINKS
------------------------------------------
1 | 'master' | 2,3
2 | 'secondary' | 1
3 | 'secondary' | 1
...
我尝试过使用COALESCE
和JOIN
,但收效甚微,有什么办法可以做到这一点吗
链接列必须是“CSV格式”,所以它可以直接由C++代码使用,而不需要大量的循环,或者每个实体都有一个查询,这大大减慢了。
如果您知道如何将其放入视图中,视图也很好?我认为这将为您提供所需内容。这将使用需要SQL Server 2017或更高版本的
STRING\u AGG
。如果您使用的是较旧版本的SQL Server,那么可以使用STUFF
和FOR XML PATH
(我认为Harry在上面提到了这一点)
你认为这会给你所需要的东西吗
select e.entity_id, e.entity_type, STUFF((SELECT distinct ',' + cast(l.secondary_id as varchar(20))
from links l
where l.master_id = e.entity_id
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'') as entity_links
from entity_table e
inner join links l on l.master_id = e.entity_id
group by e.entity_id, e.entity_type
union
select e.entity_id, e.entity_type, STUFF((SELECT distinct ',' + cast(l.master_id as varchar(20))
from links l
where l.secondary_id = e.entity_id
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'') as entity_links
from entity_table e
inner join links l on l.secondary_id = e.entity_id
group by e.entity_id, e.entity_type
我想这会给你你想要的。这将使用需要SQL Server 2017或更高版本的
STRING\u AGG
。如果您使用的是较旧版本的SQL Server,那么可以使用STUFF
和FOR XML PATH
(我认为Harry在上面提到了这一点)
你认为这会给你所需要的东西吗
select e.entity_id, e.entity_type, STUFF((SELECT distinct ',' + cast(l.secondary_id as varchar(20))
from links l
where l.master_id = e.entity_id
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'') as entity_links
from entity_table e
inner join links l on l.master_id = e.entity_id
group by e.entity_id, e.entity_type
union
select e.entity_id, e.entity_type, STUFF((SELECT distinct ',' + cast(l.master_id as varchar(20))
from links l
where l.secondary_id = e.entity_id
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'') as entity_links
from entity_table e
inner join links l on l.secondary_id = e.entity_id
group by e.entity_id, e.entity_type
您应该能够使用不同的on子句连接到链接两次,然后合并以获得相关实体的列表。然后使用string_agg将它们全部放在一行上,如下所示:
SELECT e1.entity_id,
e1.entity_type,
string_agg(COALESCE(l1.secondary_id, l2.master_id), ',')
FROM entities e1
LEFT JOIN links l1 ON (e1.entity_id = l1.master_id AND e1.entity_type = 'master')
LEFT JOIN links l2 ON (e1.entity_id = l2.secondary_id AND e1.entity_type = 'secondary')
GROUP BY e1.entity_id;
您应该能够使用不同的on子句连接到链接两次,然后合并以获得相关实体的列表。然后使用string_agg将它们全部放在一行上,如下所示:
SELECT e1.entity_id,
e1.entity_type,
string_agg(COALESCE(l1.secondary_id, l2.master_id), ',')
FROM entities e1
LEFT JOIN links l1 ON (e1.entity_id = l1.master_id AND e1.entity_type = 'master')
LEFT JOIN links l2 ON (e1.entity_id = l2.secondary_id AND e1.entity_type = 'secondary')
GROUP BY e1.entity_id;
查找XML的内容。。有很多例子there@Harry有什么例子吗?我不确定我是否理解您的意思XML与此有什么关系@HarryThis讲述了一个家庭的所有故事。而不是想如何去对数据进行反编译(并且可能在C++代码中SQL注入漏洞),你应该重构C++代码来处理SETUP。2017,介绍了@ GBeaveStRungAgg()。XML/STUFF方法是聚合字符串、查找XML内容的更好方法之一。。有很多例子there@Harry有什么例子吗?我不确定我是否理解您的意思XML与此有什么关系@HarryThis讲述了一个家庭的所有故事。而不是想如何去对数据进行反编译(并且可能在C++代码中SQL注入漏洞),你应该重构C++代码来处理SETUP。2017,介绍了@ GBeaveStRungAgg()。XML/STUFF方法是聚合字符串的更好方法之一,