假设我有一个名为“层次结构”的表,其中有两列:“经理”和“下属”
此表中的每个条目显示了经理与其管理的员工之间的关系。例如:
manager subordinate
CEO regional_director
CEO store_manager
regional_director store_manager
store_manager cashier我的问题是如何获得每一位经理的下属人数,是否?
明确定义了,例如首席执行官是regional_director的经理(CEO ->地区主管)
或
隐式定义,例如regional_director是出纳员的经理
(regional_director -> store_manager -->出纳员)。
表中数据条目的问题是,虽然经理与其下属的之间的隐含关系应该由计算到所管理的员工的数量,但在表中也可能有一个条目,两者之间有明确的关系,不应计算两次。例如:
CEO --> regional_director
regional_director --> store_manager
**BUT ALSO**
CEO --> store_manager另一方面,,
regional_director --> store_manager
store_manager --> cashier
**but there does NOT exist a relation:**
regional_director --> cashier由于这个查询将在JDBC中运行,所以可以使用java操作输出以获得所需的结果,但是我更喜欢使用sql。
此示例的输出如下:
Employee num_subordinates
CEO 3
regional_director 2
store_manager 1在考虑解决方案时,我意识到我的问题可以用有向无圈图建模,如下所示:

其中顶点是雇员,有向边的意思是‘管理者’。
就图而言,我相信我的问题会转化为:对于每个顶点v,有多少其他顶点可以用从顶点v开始的任意长度的路径到达?
顶点7可以到达顶点8,9,11,2,10,所以它的值是5
很抱歉有这么长的问题。
发布于 2015-12-09 05:13:07
简单的版本如下:
with tree (manager, subordinate) as (
select manager ,subordinate from hierarchy
union all
select t.manager, h.subordinate from tree t
join hierarchy h
on t.subordinate = h.manager
) select manager, count(distinct subordinate )
from tree
group by manager它可以通过删除下一个循环中已经存在的节点来改进。但是,也可以通过使用在count中的简单区分来实现这一目的。
下面是示例:SQL Fiddle
它还可以改进与无休止的回路保护。
with tree (manager, subordinate, path) as (
select manager ,subordinate, manager || '->' || subordinate from hierarchy
union all
select t.manager, h.subordinate, t.path || '->' || h.subordinate from tree t
join hierarchy h
on t.subordinate = h.manager
where instr(path, h.subordinate) = 0
) select manager , count(distinct subordinate)
from tree
group by manager我们在这里使用路径,它显示节点之间的跳跃。如果从属已经在路径上,那么跳过它。
样本在这里:SQL Fiddle
发布于 2015-12-09 05:03:29
使用标准SQL进行比较接近的一种方法是为每个级别(直接、间接级别-1、间接级别-2)使用一组语句,不包括已经计算过的语句。直接和第一级案件的下面是一个例子:
-- count direct reports
-- count indirect-at-one-level-of-separation reports
-- excluding counted-elsewhere (direct) reports
select 1, manager, count(*)
from hierarchy
group by manager
union
select 2, h1.manager, count(*)
from hierarchy h1, hierarchy h2
where h1.subordinate=h2.manager
and not exists (
select i1.manager
from hierarchy i1
where i1.manager=h1.manager
and i1.subordinate=h2.subordinate
)
group by h1.manager
order by 2, 1你需要把这些条目加起来。但随着水平的提高,这将变得非常混乱。甲骨文的connect by可能会有所帮助--我还没试过。
我猜这是一个用Java做工作的例子,也许使用一个集合?
https://stackoverflow.com/questions/34170562
复制相似问题