Получить значения атрибута из родительского элемента - просто по sql - PullRequest
0 голосов
/ 03 декабря 2018
  • У меня есть одна таблица с сотрудниками.
  • Каждый сотрудник может иметь одного босса / родителя (но также может быть и нулевым).
  • Каждый сотрудник высшего уровня имеет значение в поле столбца.
  • Все его дети наследуют это значение в коде, но не в базе данных.

Пример:

| 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).

Заранее спасибо!

1 Ответ

0 голосов
/ 03 декабря 2018

Вам нужно рекурсивное общее табличное выражение , чтобы пройти по дереву.Вам также необходимо «передать» ненулевые значения от родителя к потомкам, чтобы имитировать наследование значений.

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

...