SQL 递归查询 Postgres

SQL Recursive query Postgres

所以我有一个 table 公司信息,其数据如下:

company |    role      |    person
--------|--------------|------------
Google  | dev          | John
Google  | tester       | Bob
Facebook| manager      | Alex
Facebook| blah         | Bob

我想通过 "connections" 约翰认识多少人。因此,如果 John 和 Bob 在 Google 工作,John 通过 1 个连接认识 Bob,但是如果 John 认识 Bob 并且 Bob 认识 Alex,那么 John 也通过扩展认识 alex,但是通过 Bob 意味着 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

澄清: 如果两个人在同一家公司工作,我们假设他们彼此认识。所以该图看起来像这样:

|John|--dev--|Google|--tester--|Bob|--blah--|Facebook|

这样,人和公司就是节点,角色就是边。

基本查询是查找与给定人员在同一家公司工作的人员,在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)