sql - postgreSQL 递归 - 查找包含多个员工和其他公司不同工作的所有循环
问题描述
更具体地说,我应该使用递归 psql 来解决问题。我们有这个:
- A 是 X 公司的 CEO 和 Y 公司的董事长。
- B 人是 Y 公司的 CEO 和 Z 公司的董事。
- C 人是 Z 公司的 CEO 和 X 公司的副主席。
使用递归 SQL,找到包含 3、4 或 5 名员工的所有周期,其中每个员工在一家公司担任 CEO,在下一个周期担任董事、副主席或董事长。
-- This is the table in mind:
CREATE TABLE info (
company text
job text
employee text
primary key (company, job, employee)
);
-- Desired result
Cycle Employee Job Company
-------------------------------------------
1 Jonathan CEO DillCO
1 Joseph CEO Joestar
2 Jonathan Chairman Joestar
2 Joseph Director DillCO
我不是特别擅长 SQL,但我正在学习。你可以按照你想要的方式解释这个问题,它不需要完全像我想要的输出(因为这是我对它的解释)。
以下是您可以插入表中的一些示例数据:
insert into info values('Bolk', 'CEO', 'Stein Hald');
insert into info values('Forsk', 'Chairman', 'Stein Hald')
insert into info values('Bolk', 'Chairman', 'Guro Dale');
insert into info values('Bolk', 'Director', 'Rolf Numme');
insert into info values('Bonn', 'CEO', 'Hauk Storm');
insert into info values('Bonn', 'Chairman', 'Live Brog');
insert into info values('Bonn', 'Director', 'Tor Fjeld');
insert into info values('Braga', 'CEO', 'Truls Lyche');
insert into info values('Hiro', 'Deputy chairman', 'Rolf Numme');
insert into info values('Hafn', 'Chairman', 'Hauk Storm');
这是我所拥有的:
-- so far, finds all CEOs recursively in the first cycle
WITH RECURSIVE cycle (emp, job, comp, cyclenr) AS (
SELECT si.employee, si.job, si.company, 1
FROM info si
UNION ALL
SELECT c.emp, c.job, c.comp, c.cyclenr+1
FROM cycle c
JOIN info c2 on c.emp = c2.employee
WHERE cyclenr < 1
)
SELECT * FROM cycle
WHERE job = 'CEO';
这只会找到第一个周期中的所有 CEO,但我遇到了其他问题。
解决方案
这是一个想法。过滤到只有 CEO。然后生成它们的所有组合并检查循环。
对于 3 个周期,这看起来像:
with ec as (
select distinct employee, company
from info
where job = 'CEO'
)
select *
from ec ec1 join
ec ec2
on ec1.employee <> ec2.employee join
ec ec3
on ec3.employee not in (ec1.employee, ec2.employee)
where exists (select 1
from info i
where i.employee = ec2.employee and i.company = ec1.company and i.job in ('Chairman', 'Director')
) and
exists (select 1
from info i
where i.employee = ec3.employee and i.company = ec2.company and i.job in ('Chairman', 'Director')
) and
exists (select 1
from info i
where i.employee = ec1.employee and i.company = ec3.company and i.job in ('Chairman', 'Director')
) ;
这是一个例子。
推荐阅读
- javascript - socket.emit 仅在递归函数(使用 requestAnimationFrame 实现)终止后才有效
- numpy - pytorch 与 autograd.numpy
- django - Django 管理器将 m2m 的第一个元素注释为 fk
- php - 无法将多选下拉值保存到数据库
- pdf - 为什么 PDF 表单的互操作性如此不同?
- sas - SAS:如何在 libname 语句中防止“警告:未解析宏的明显调用”?
- c++ - 从 VS6 升级到 VS2017 数学差异
- hybris - SAP Hybris Backoffice - 默认打开高级搜索
- r - unloadNamespace(package) 中的错误:命名空间“MASS”由“vegan”导入,因此无法卸载
- apache-flink - 使用 Flink-Kafka 连接器均匀消费事件