2014-06-20 2 views
0

MySql에서 중첩 된 집합으로 인접 목록을 변환해야합니다. 나는 인접리스트를 mysql (http://data.bangtech.com/sql/nested_set_treeview.htm)을 사용하는 중첩 된 세트로 변환하기 위해 인터넷을 통해서 오직 하나의 자원만을 발견했다. 코드도 같은 웹 페이지에 있습니다.중첩 된 테이블을 중첩 된 집합으로 변환

CREATE TABLE test.Tree 
(emp CHAR(10) NOT NULL, 
boss CHAR(10)); 

CREATE TABLE test.Personnel(
emp CHAR(20) PRIMARY KEY, 
boss CHAR(20) REFERENCES Personnel(emp), 
salary DECIMAL(6,2) NOT NULL 
); 

INSERT INTO test.Personnel VALUES ('jerry', 'NULL',1000.00); 
INSERT INTO test.Personnel VALUES ('Bert', 'jerry',900.00); 
INSERT INTO test.Personnel VALUES ('chuck', 'jerry',900.00); 
INSERT INTO test.Personnel VALUES ('donna', 'chuck',800.00); 
INSERT INTO test.Personnel VALUES ('eddie', 'chuck',700.00); 
INSERT INTO test.Personnel VALUES ('fred', 'chuck',600.00); 


INSERT INTO test.Tree 
SELECT emp, boss FROM test.Personnel; 

필자는 Personnel 테이블의 트리 테이블을 만듭니다. 트리 테이블에는 보스 - 직원 계층 구조가 있습니다. 이것은 인접 목록입니다. 이를 중첩 세트로 변환하기 위해이 코드를 적용했습니다.

BEGIN ATOMIC 
DECLARE counter integer; 
DECLARE max_counter integer; 
DECLARE current_top integer; 


SET counter = 2; 
SET max_counter = 2 * (SELECT COUNT(*) FROM test.Tree); 
SET current_top = 1; 

INSERT INTO test.Stack 
SELECT 1, emp, 1, NULL 
FROM test.Tree 
WHERE boss IS NULL; 

DELETE FROM test.Tree 
WHERE boss IS NULL; 

WHILE counter <=(max_counter - 2) 
LOOP IF EXISTS (SELECT * FROM test.Stack AS S1, test.Tree AS T1 
    WHERE S1.emp = T1.boss AND S1.stack_top = current_top) 
THEN 
BEGIN -- push when top has subordinates, set lft value 
    INSERT INTO test.Stack 
    SELECT (current_top + 1), MIN(T1.emp), counter, NULL 
    FROM test.Stack AS S1, test.Tree AS T1 
    WHERE S1.emp = T1.boss 
    AND S1.stack_top = current_top; 

    DELETE FROM test.Tree 
    WHERE emp = (SELECT emp 
    FROM test.Stack 
    WHERE stack_top = current_top + 1); 

    SET counter = counter + 1; 
    SET current_top = current_top + 1; 
    END 
    ELSE 
    BEGIN -- pop the stack and set rgt value 
    UPDATE test.Stack 
    SET rgt = counter, 
    stack_top = -stack_top -- pops the stack 
    WHERE stack_top = current_top 
    SET counter = counter + 1; 
    SET current_top = current_top - 1; 
    END IF; 
    END LOOP; 
    END; 

MySQL Workbench에서 제거 할 수없는 몇 가지 구문 오류가 표시됩니다.

나는 아주 기본적인 mysql 작업에만 익숙하므로 코드를 직접 디버깅 할 수 없습니다. 이 모든 오류를 제거하는 방법은 무엇입니까? Plz 도움말. 위 작업을 수행 한 두 번째 소스는 http://www.sqlservercentral.com/articles/Hierarchy/94040/이지만 코드는 T Sql에 있으며 MySQL로 변환 할 수있는 충분한 기술이 없습니다.

+0

당신이 무엇을보고 오류에 대한 자세한 특정 될 수 있을까? – Jordan

+0

@Jordan은 mysqlworkbench (https://www.flickr.com/photos/[email protected]/14281712368/in/photostream/)의 장면 사진입니다. 코드를 실행하면 오류 코드 : 1064가 표시되며 코드에 구문 오류가 있습니다. – dodgeballer

답변

0

당신은 줄에 'NULL'을 NULL 넣어 안

INSERT INTO test.Personnel의 VALUES ('제리', 'NULL', 1000.00);

올바른 버전 :

INSERT INTO test.Personnel의 VALUES ('제리', NULL, 1000.00);

0

사용 배쉬 :

배쉬 변환 :

# SQL command to fetch necessary fields, output it to text archive "tree" 
SELECT id, parent_id, name FROM projects; 

# Make a list "id|parentid|name" and sort by name 
cat tree | 
    cut -d "|" -f 2-4 | 
    sed 's/^ *//;s/ *| */|/g' | 
    sort -t "|" -k 3,3 > list 

# Creates the parenthood chain on second field 
while IFS="|" read i p o 
do 
    l=$p 
    while [[ "$p" != "NULL" ]] 
    do 
    p=$(grep -w "^$p" list | cut -d "|" -f 2) 
    l="$l,$p" 
    done 
    echo "$i|$l|$o" 
done <list> listpar 

# Creates left and right on 4th and 5th fields for interaction 0 
let left=0 
while IFS="|" read i l o 
do 
    let dif=$(grep "\b$i,NULL|" listpar | wc -l)*2+1 
    let right=++left+dif 
    echo "$i|$l|$o|$left|$right" 
    let left=right 
done <<< "$(grep "|NULL|" listpar)" > i0 

# The same for following interactions 
n=0 
while [ -s i$n ] 
do 
    while IFS="|" read i l nil left nil 
    do 
    grep "|$i,$l|" listpar | 
    while IFS="|" read i l o 
    do 
     let dif=$(grep "\b$i,$l|" listpar | wc -l)*2+1 
     let right=++left+dif 
     echo "$i|$l|$o|$left|$right" 
     let left=right 
    done 
    done < i$n > i$((++n)) 
done 

# Show concatenated 
cat i*|sort -t"|" -k 4n 

# SQL commands 
while IFS="|" read id nil nil left right 
do 
    echo "UPDATE projects SET lft=$left, rgt=$right WHERE id=$id;" 
done <<< "$(cat i*)"