【问题标题】:How to create a hierarchical tree in SQL with two kinds of nodes?如何在 SQL 中创建具有两种节点的层次树?
【发布时间】:2015-09-10 02:28:01
【问题描述】:

我有下一张桌子tree

 id, name, boss, group
 1, Boss 1, 9, false
 2, Boss 2, 9, false
 3, Group 1, 1, true
 4, Group 2, 2, true
 5, Employee 1, 3, false
 6, Employee 2, 3, false
 7, Employee 3, 3, false
 8, Employee 4, 4, false
 9, Boss 0, null, false

必须用下一种方式表示:

Boss 0 
|___  Boss 1 
|    |-- Group 1
|    |________ Employee 1
|    |________ Employee 2
|    |________ Employee 3
|___ Boss 2
     |-- Group 2
     |________ Employee 4

我可以得到这个结果:

id, name, level 
9, Boss 0, 1
1, Boss 1, 2
2, Boss 2, 2
3, Group 1, 3
4, Group 2, 3
5, Employee 1, 4
6, Employee 2, 4
7, Employee 3, 4
8, Employee 4, 4

使用下一个查询:

WITH RECURSIVE t(id, name, boss, level, group) AS
(
 SELECT
     p1.id,
     p1.name,
     p1.boss,
     1 as level,
     p1.group
     FROM tree as p1
     WHERE p1.boss is null
 UNION ALL
 SELECT p2.id,
     p2.name,
     p2.boss,
     CASE WHEN p2.group = true THEN level + 1
         WHEN p2.group is null THEN level
     END,
     p2.group
 FROM tree as p2
     INNER JOIN t on p2.boss = t.id
 )
 SELECT * FROM t WHERE t.group is null

但是,我需要得到的是下一个信息:每个员工下面直接和间接有多少人?例如:

Boss 0:
   2 Direct
   4 Indirect

也就是说,我正在寻找的是这样的:

id, name, level 
9, Boss 0, 1
1, Boss 1, 2
2, Boss 2, 2
3, Group 1, 3
4, Group 2, 3
5, Employee 1, 3
6, Employee 2, 3
7, Employee 3, 3
8, Employee 4, 3

在这种情况下我该怎么办?您认为使用嵌套集模型解决此类问题是否更好?

【问题讨论】:

  • 您使用的是哪个 DBMS? Postgres?
  • 是的 @a_horse_with_no_name ,我正在使用 Postgres。

标签: sql postgresql hierarchy hierarchical-data


【解决方案1】:

您没有指定 RDBMS,所以我使用 SQL Server:

SqlFiddleDemo

WITH t(id, name, boss, [level], [group]) AS
(
  SELECT
     p1.id,
     p1.name,
     p1.boss,
     1 as [level],
     p1.[group]
   FROM tree as p1
   WHERE p1.boss IS NULL
   UNION ALL
   SELECT 
     p2.id,
     p2.name,
     p2.boss,
     CASE WHEN t.[group] = 0 THEN [level] + 1
         ELSE [level]
     END,
     p2.[group]
   FROM tree as p2
   JOIN t 
     ON p2.boss = t.id
 )
SELECT * 
FROM t 

【讨论】:

  • 示例中的 recursive 关键字(需要 SQL 标准)建议使用 Postgres 或 Firebird
  • @a_horse_with_no_name 我希望我更了解他们。 SQL Server 主要是 :)
  • 是的,我正在使用 Postgres
  • 谢谢,case 中的条件是有道理的;当group 为假时,级别保持不变。
猜你喜欢
  • 1970-01-01
  • 2022-01-09
  • 2010-09-17
  • 1970-01-01
  • 2017-04-15
  • 2021-09-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多