繁体   English   中英

SQL递归查询Postgres

[英]SQL Recursive query Postgres

所以我有一个表companyinfo,它的数据如下:

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

我想通过约翰了解人们有多少个“联系”。 因此,如果约翰和鲍勃在Google工作,那么约翰会通过1个关联来了解鲍勃,但是如果约翰知道鲍勃并且鲍勃也知道亚历克斯,那么约翰也会通过扩展名来识别alex,但是通过鲍勃意味着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;

但这显然行不通,是的,它确实找到了亚历克斯,但不是因为通过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)    

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM