所以我有一个表companyinfo,其数据如下:
company | role | person
--------|--------------|------------
Google | dev | John
Google | tester | Bob
Facebook| manager | Alex
Facebook| blah | Bob
我想找到多少"连接"约翰认识人吗?因此,如果约翰和鲍勃在谷歌工作约翰通过1连接知道鲍勃,但如果约翰知道鲍勃和鲍勃知道亚历克斯比约翰也知道亚历克斯扩展,但通过鲍勃意味着2连接
我理解这是在代码中解决的非常简单的图形问题,但我一直在试图弄清楚如何编写递归sql来执行这几个小时并且只提出:
WITH RECURSIVE search_graph(person, company, n) AS (
SELECT s.person, s.company, 1
FROM companyinfo s
WHERE s.person = 'John'
UNION
SELECT s.person, s.company, n+1
FROM companyinfo s, search_graph sg
WHERE s.person = 'Alex'
)
SELECT * FROM search_graph limit 50;
但它显然不起作用,是的它确实找到了Alex,但不是因为通过bob和循环不忠而跟随连接因此limit 50
澄清: 如果两个人在同一家公司工作,我们假设他们互相认识。所以图表看起来像这样:
|约翰| --dev-- |谷歌| --tester-- |鲍勃| --blah-- | Facebook的|
这样人们和公司就是节点,角色就是边缘。
答案 0 :(得分:1)
基本查询找到在同一家公司工作的人与某个人在SQL中转换为companyinfo
的自联接。此外,应该使用一系列人来消除重复。
with recursive search_graph(person, persons) as (
select s2.person, array['John']
from companyinfo s1
join companyinfo s2
on s1.company = s2.company and s1.person <> s2.person
where s1.person = 'John'
union
select s2.person, persons || s1.person
from companyinfo s1
join companyinfo s2
on s1.company = s2.company and s1.person <> s2.person
join search_graph g
on s1.person = g.person
where s1.person <> all(persons)
)
select distinct persons[cardinality(persons)] person, cardinality(persons) n
from search_graph
order by 2;
person | n
--------+---
John | 1
Bob | 2
Alex | 3
(3 rows)