Самореферентный класс: Как получить иерархическую структуру сотрудников в компании?

У меня есть класс, определенный в Python, с именем Employees. Его атрибут id_supervisor — это id сотрудника, который за него отвечает.

Один сотрудник может отвечать за (контролировать) многих других сотрудников.

Это мой класс:

class Employee(DeclarativeBase):

    __tablename__ = 'employees'

    id_ = Column('id',Integer,primary_key=True)
    name = Column(Unicode(50))
    id_supervisor = Column(Integer, ForeignKey('employees.id'))
    #other attributes ...

Что мне нужно сделать, так это получить всю иерархическую структуру компании, от босса компании (его атрибут id_supervisor должен быть установлен на None или самому себе) до самого нижнего рабочего в компании (он не будет контролировать рабочих). вообще).

Как это можно сделать? Я думал об использовании рекурсивной функции, но я действительно не знаю, как это сделать.

Любая помощь будет оценена по достоинству.


person Xar    schedule 26.12.2013    source источник
comment
Ваша концепция/дизайн таблицы кажется достаточной. Как выглядит ваш источник этой информации? Это, я думаю, определит ваши следующие шаги.   -  person    schedule 26.12.2013
comment
Это основная проблема шаблона списка смежности — вы не можете получить целое дерево (или целую ветвь дерева) в одном запросе. Вместо этого вы можете рассмотреть возможность использования шаблона вложенных наборов (также известного как модифицированный обход дерева предварительного заказа): mikehillyer.com/articles/managing-hierarchical-data-in-mysql   -  person bruno desthuilliers    schedule 26.12.2013


Ответы (1)


Попробуйте материал https://class.coursera.org/db/wiki/coursematerials. . Вы можете увидеть раздел о рекурсии (Рекурсия в SQL). Это очень хорошо объясняется на примерах PostgreSQL.

postgres=# select * from employees ;
 empid | supervisorid 
-------+--------------
     1 |             
     2 |             
     3 |            1
     4 |            2
     5 |            3
     6 |            4
(6 rows)

WITH RECURSIVE emp(empid,supervisorid) AS (
     SELECT empid, supervisorid  FROM employees where empid=1
     UNION ALL
     SELECT e.empid, e.supervisorid
     FROM emp s, employees e
     WHERE e.supervisorid = s.empid 
   )
SELECT * 
 FROM emp
 ;
 empid | supervisorid 
-------+--------------
     1 |             
     3 |            1
     5 |            3
(3 rows)
person Jayadevan    schedule 26.12.2013