تم استخدام الرسم البياني لتنفيذ التبعية بين الموظفين ، بدلاً من طريقة الجد-الطفل المستخدمة سابقًا في جدول القسم.
تبين أن التجربة كانت ناجحة ، فربما تكون مفيدة لشخص ما وتساعد في توفير الوقت. في وقت ما كنت أبحث عن تطبيق على pqSQL ، لكن يبدو أنني كنت أبدو سيئًا. كان علي أن أنفذها بنفسي. الذي ، بشكل عام ، حتى للأفضل ، المهمة مثيرة للاهتمام ، من الجيد دائمًا أن تفعل شيئًا بيديك ، حتى لا يضيع الوقت.
ادخال البيانات
بشكل عام ، هناك جدول قياسي "منصب الموظف" مع معرف المفتاح الأساسي . المناصب لها تسلسل هرمي من تبعية "كبير الموظفين". الفكرة هي أن الروابط بين المنشورات يتم تخزينها في رسم بياني منفصل للكيان .
تم استخدام خوارزمية Dijkstra للعثور على مسار في الرسم البياني ، ويمكن العثور على وصف عام ، على سبيل المثال ، هنا
انتاج |
- قائمة الموظفين المرؤوسين لهذا الغرض
- قائمة الرؤساء لهذا الموظف
- هل الموظف مرؤوس لهذا
- قائمة الموظفين المرؤوسين لهذا (المسار من الرئيس إلى الموظف)
التنفيذ باستخدام PL / pgSQL
تخزين الرسم البياني كجدول من الحواف
القمم هي قيم معرف الجدول الهدف.
CREATE TABLE graph
(
vertex integer NOT NULL , --id
edge integer NOT NULL , --id
vertex_order integer NOT NULL -- ( 0 , 1 )
);
لتوليد معرف الحافة ، استخدم التسلسل
CREATE SEQUENCE enge_seq OWNED BY graph.edge;
ملء طاولة الحافة
يتم استخدام عمليتي INSERT لإدراج حافة جديدة (الرؤوس id0 ، id1 )
-- id
new_id = nextval('enge_seq');
--
INSERT INTO graph (vertex , edge , vertex_order ) VALUES ( id0 , new_id , 0 );
--
INSERT INTO graph (vertex , edge , vertex_order ) VALUES ( id1 , new_id , 1 );
استرداد قائمة الموظفين المرؤوسين لمعرّف Current_id معين
SELECT
id
FROM
graph
WHERE
vertex_order = 1 AND
edge IN (SELECT edge FROM graph WHERE vertex = current_id AND vertex_order = 0 );
الحصول على قائمة الرؤساء للمعرّف الحالي
SELECT
id
FROM
graph
WHERE
vertex_order = 0 AND
edge IN (SELECT edge FROM graph WHERE vertex = current_id AND vertex_order = 1 );
إنشاء مصفوفة الإتاحة (خوارزمية Dijkstra) من start_id قمة الرأس
إنشاء جدول مؤقت tmp_matrix
CREATE TEMPORARY TABLE tmp_matrix
AS
(
SELECT
DISTINCT vertex ,
FALSE AS label ,
999999 AS distance ,
FALSE AS is_finish
FROM
graph
);
السكان الأولي لجدول tmp_matrix
UPDATE tmp_matrix
SET label = TRUE , distance = 0
WHERE vertex = current_id ;
current_id = start_id ;
SELECT
distance
INTO
current_distance
FROM
tmp_matrix
WHERE
vertex = current_id;
SELECT
EXISTS (SELECT 1 FROM tmp_matrix WHERE label = FALSE )
INTO
not_visit;
ملء مصفوفة التوافر
WHILE not_visit
LOOP
FOR v_rec IN
SELECT
*
FROM
tmp_matrix
WHERE
NOT label AND
--
vertex IN ( SELECT
id
FROM
graph
WHERE
vertex_order = 1 AND
edge IN (SELECT
edge
FROM
graph
WHERE
vertex = current_id AND vertex_order = 0 ))
LOOP
--
IF v_rec.distance > (current_distance +1)
THEN
UPDATE tmp_matrix SET distance = (current_distance +1) WHERE vertex = v_rec.vertex;
END IF ;
--
IF SELECT
NOT EXISTS
(
SELECT 1 FROM graph WHERE vertex = v_rec.vertex AND vertex_order = 0
)
THEN
UPDATE tmp_matrix SET label = TRUE , is_finish = TRUE WHERE vertex = v_rec.vertex;
END IF ;
END LOOP;
UPDATE tmp_matrix SET label = TRUE WHERE vertex = current_id ;
--
SELECT
vertex
INTO
current_id
FROM
tmp_matrix
WHERE
NOT label AND
distance < 999999 ;
SELECT
distance
INTO
current_distance
FROM
tmp_matrix
WHERE
vertex = current_id ;
SELECT
EXISTS (SELECT 1 FROM tmp_matrix WHERE label = FALSE )
INTO
not_visit ;
IF current_id IS NULL
THEN
not_visit = FALSE ;
END IF;
END LOOP;
قم بإرجاع مصفوفة الإتاحة الناتجة
SELECT
vertex ,
label ,
distance ,
is_finish
FROM
tmp_matrix
WHERE
distance != 999999 ;
ما إذا كان الموظف الذي لديه check_id تابعًا لـ start_id المحدد أم لا
احصل على مصفوفة التوفر لـ start_id (انظر أعلاه).
IF EXISTS
( SELECT distance FROM tmp_matrix WHERE vertex = check_id )
THEN
RETURN TRUE;
ELSE
RETURN FALSE;
END IF;
قائمة الموظفين المرؤوسين لهذا واحد (المسار من بداية رئيسه إلى معرف انتهاء الموظف)
احصل على مصفوفة التوفر لـ start_id (انظر أعلاه).
قم بملء جدول المسار بين جدولي start_id و finish_id
current_id = finish_id ;
result[1] = finish_id ;
WHILE current_id != start_id
LOOP
SELECT
par.id
FROM
( SELECT
id
FROM
graph
WHERE
vertex_order = 0 AND
edge IN (SELECT
edge
FROM
graph
WHERE
vertex = current_id AND vertex_order = 1 )) par
JOIN tmp_matrix m ON ( par.id = m.vertex )
INTO
parent_id
LIMIT 1 ;
SELECT
array_append( result , parent_id )
INTO
result ;
--
current_id = parent_id ;
END LOOP;
النتيجة في مجموعة نتيجة يتكون كمجموعة مسار معرف في ترتيب عكسي. لسهولة المشاهدة ، يمكن عكس المصفوفة بأي طريقة.