将名称之间的链接列表合并到一个列中

Coalesce list of links between names into a single column

我目前有两个 table 用于存储实体之间的关系,如下所示:

Entity_Table:包含名称和类型(master or secondary)实体数

ENTITY_ID  |  ENTITY_NAME  |  ENTITY_TYPE
-----------------------------------------
1          |  'entity_1'   |  'master'
2          |  'entity_2'   |  'secondary'
3          |  'entity_3'   |  'secondary'
...

链接table:包含实体之间的关系信息

MASTER_ID  |  SECONDARY_ID
--------------------------
1          |  2
1          |  3
...

附加信息:

我在找什么:一个查询 return 所有实体及其链接实体的格式如下:

ENTITY_ID  |  ENTITY_TYPE  |  ENTITY_LINKS
------------------------------------------
1          |  'master'     |  2,3
2          |  'secondary'  |  1
3          |  'secondary'  |  1
...

我已经尝试使用 COALESCEJOIN 但收效甚微,关于如何实现这一点有什么想法吗?

链接列必须采用 "csv-like" 格式,以便后面的 c++ 代码可以直接使用它,而无需大量的 for 循环或每个实体都有一个查询,这会大大降低速度。

如果您知道如何将其放入视图中,视图也很不错?

我想这会给你你想要的。这使用 STRING_AGG 需要 SQL Server 2017 或更新版本。如果您使用的是旧版本的 SQL 服务器,您可以使用 STUFFFOR XML PATH(我认为 Harry 在上面所说的)。

select e.entity_id, e.entity_type, string_agg(l.secondary_id, ',') 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, string_agg(l.master_id, ',') 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

认为这会为您提供使用 STUFF 所需的内容。

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;