SELECT P2.emp, SUM(S1.salary)FROM Personnel AS P1, Personnel AS P2, Salaries AS S1WHERE P1.lft BETWEEN P2.lft AND P2.rgt AND P1.emp = S1.empGROUP BY P2.emp;
在邻接表模型中,你必须使用游标来完成这个功能。
找到每个节点的级别,以便你可以将树打印为缩进列表。
SELECT COUNT(P2.emp) AS indentation, P1.empFROM Personnel AS P1, Personnel AS P2WHERE P1.lft BETWEEN P2.lft AND P2.rgtGROUP BY P1.empORDER BY P1.lft;
嵌套集模型具有邻接表模型没有的兄弟姐妹的隐含排序。插入一个新的节点作为最右边节点的兄弟节点。
BEGINDECLARE right_most_sibling INTEGER; SET right_most_sibling = ( SELECT rgt FROM Personnel WHERE emp = :your_boss); UPDATE Personnel SET lft = CASE WHEN lft > right_most_sibling THEN lft +2 ELSE lft END, rgt = CASE WHEN rgt >= right_most_sibling THEN rgt +2 ELSE rgt END WHERE rgt >= right_most_sibling; INSERT INTO Personnel (emp, lft, rgt) VALUES('New Guy', right_most_sibling, (right_most_sibling +1))END;
要将邻接表模型转换为嵌套集模型,请使用下推堆栈算法。假设我们有这些表:
树持有邻接表模型。
CREATE TABLE Tree(emp CHAR(10) NOT NULL,boss CHAR(10));INSERT INTO TreeSELECT emp, boss FROM Personnel;-- Stack starts empty, will holds the nested set modelCREATE TABLE Stack(stack_top INTEGER NOT NULL,emp CHAR(10) NOT NULL,lft INTEGER,rgt INTEGER);BEGIN ATOMICDECLAREcounter INTEGER;DECLARE max_counter INTEGER;DECLARE current_top INTEGER; SET counter=2; SET max_counter =2* ( SELECT COUNT(*) FROM Tree); SET current_top =1; INSERT INTO Stack SELECT1, emp,1, NULL FROM Tree WHERE boss IS NULL; DELETE FROM Tree WHERE boss IS NULL; WHILE counter<= (max_counter -2) LOOP IF EXISTS ( SELECT* FROM Stack AS S1, Tree AS T1 WHERE S1.emp = T1.boss AND S1.stack_top = current_top) THENBEGIN-- push when top has subordinates, set lft value INSERT INTO Stack SELECT (current_top +1), MIN(T1.emp), counter, NULL FROM Stack AS S1, Tree AS T1 WHERE S1.emp = T1.boss AND S1.stack_top = current_top; DELETE FROM Tree WHERE emp = ( SELECT emp FROM Stack WHERE stack_top = current_top +1); SET counter=counter+1; SET current_top = current_top +1;ENDELSE BEGIN-- pop the stack and set rgt value UPDATE Stack SET rgt =counter, stack_top =- stack_top -- pops the stack WHERE stack_top = current_top SETcounter=counter+1; SET current_top = current_top -1;END IF;END LOOP;END;