【问题标题】:Get attribute values from parent element - just by sql从父元素获取属性值 - 仅通过 sql
【发布时间】:2019-05-04 15:58:45
【问题描述】:
  • 我有一张员工桌。
  • 每个员工都可以有一个老板/父母(但也可以为空)。
  • 每个顶级员工在列 floor 中都有一个值。
  • 他所有的孩子都继承了这个 代码中的值,但不在数据库中。

示例:

| id    | name    | parent_id | floor    |
|----------------------------------------|
| 1     | boss1   | null      | green    | 
| 2     | emp1    | 1         | null     |
| 3     | boss2   | null      | blue     |
| 4     | emp3    | 3         | null     |
| 5     | emp4    | 2         | null     |

现在我想回答一个问题,即哪些员工在绿色楼层工作(显而易见的答案:boss1、emp1 和 emp4)?我知道以编程方式很容易,但我只想使用 SQL (Postgres) 来完成。

提前致谢!

【问题讨论】:

    标签: sql postgresql hierarchical-data recursive-query


    【解决方案1】:

    您需要recursive common table expression 才能通过树。您还需要将非空值从父级“携带”到子级,以模拟值的继承。

    with recursive tree as (
       select id, name, parent_id, floor
       from employees
       where parent_id is null
       union all
       select c.id, c.name, c.parent_id, coalesce(c.floor, p.floor) as floor
       from employees c 
         join tree p on p.id = c.parent_id
    )
    select *
    from tree;
    

    鉴于您的示例数据,以上返回:

    id | name  | parent_id | floor
    ---+-------+-----------+------
     1 | boss1 |           | green
     3 | boss2 |           | blue 
     2 | emp1  |         1 | green
     4 | emp3  |         3 | blue 
     5 | emp4  |         2 | green
    

    现在可以通过将WHERE 条件添加到最终选择来更改为返回所有带有绿色地板的行。

    with recursive tree as (
       ... as above ...
    )
    select *
    from tree
    where floor = 'green';
    

    在线示例:https://rextester.com/UQJVF54349

    【讨论】:

    • 我认为您应该将green 的过滤器放在 CTE 的锚部分中。
    • @GordonLinoff:如果老板和他/她的员工在不同的楼层工作怎么办?
    • 谢谢@a_horse_with_no_name!工作得很好。
    猜你喜欢
    • 2016-02-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-13
    相关资源
    最近更新 更多