2017-04-02 43 views
1

我有如下关系:Recusive SQL查询

公司信息(公司,角色,员工)

我想要做的就是找到两个员工之间的最短“路径”。

我需要找到乔和彼得之间的距离。 乔是A公司的首席执行官,而一个名叫Alex的人是董事会成员。 Alex是B公司的首席执行官,彼得是B公司的副总裁。那么,乔和彼得之间的距离将是2.如果乔和彼得在同一家公司担任角色,那将是1.

我需要使用递归SQL来解决这个问题。到目前为止,我已经提出了基本案例和最终选择字符串,但是我不能在我的生活中找出递归部分。

WITH RECURSIVE shortest_path(c1,p1,c2,p2, path) AS (
    -- Basecase -- 
    SELECT c1.company, c1.person, c2.company, c2.person, array[c1.person, c2.person] 
    FROM CompanyInfo c1 
    INNER JOIN CompanyInfo c2 ON c1.company = c2.company 
    WHERE c1.person = 'Joe' 
    AND c1.person <> c2.person 
UNION ALL 
    -- Recursive -- 
    -- This is where I'm stuck. 
) 

SELECT p1, p2, array_length(path,1) -1 as distance 
FROM shortest_path 
WHERE p2 = 'Peter' 
ORDER BY distance 
LIMIT 1; 

样本数据

CREATE TABLE CompanyInfo (
    company text, 
    role text, 
    employee text, 
    primary key (company, role, employee) 
); 

insert into CompanyInfo values('Company A', 'CEO', 'Joe'); 
insert into CompanyInfo values('Company A', 'Board member', 'Alex'); 
insert into CompanyInfo values('Company B', 'CEO', 'Alex'); 
insert into CompanyInfo values('Company B', 'Board member', 'Peter'); 

期望输出

person 1 | person 2 | distance 
Joe  Peter  2 
+0

标记您正在使用的dbms。 (该代码是产品特定的。) – jarlh

+0

刚刚添加了标签@jarlh –

+1

太棒了,希望您现在能够得到更好的关注! – jarlh

回答

1

试试这个。继续运行,直到新员工可以添加到路径中。

CREATE TABLE CompanyInfo (
    company text, 
    role text, 
    employee text, 
    primary key (company, role, employee) 
); 

insert into CompanyInfo values('Company A', 'CEO', 'Joe'); 
insert into CompanyInfo values('Company A', 'Board member', 'Alex'); 
insert into CompanyInfo values('Company B', 'CEO', 'Alex'); 
insert into CompanyInfo values('Company B', 'Board member', 'Peter'); 


WITH RECURSIVE shortest_path(c1,p1,c2,p2, path) AS (
    -- Basecase -- 
    SELECT c1.company, c1.employee, c2.company, c2.employee, array[c1.employee, c2.employee] 
    FROM CompanyInfo c1 
    JOIN CompanyInfo c2 ON c1.company = c2.company 
     AND c1.employee = 'Joe' 
     AND c1.employee <> c2.employee 
    UNION ALL 
    -- Recursive -- 
    SELECT c1, p1, c3.company, c3.employee, path || c3.employee 
    FROM shortest_path c1 
    JOIN CompanyInfo c2 ON c1.p2 = c2.employee  
    JOIN CompanyInfo c3 ON c3.company = c2.company 
     AND NOT c3.employee = ANY (c1.path) 
) 

SELECT *, array_length(path,1) -1 as distance 
FROM shortest_path 
WHERE p2 = 'Peter' 
ORDER BY distance 
LIMIT 1; 
+0

完美,谢谢:) –