2

階層データを収集して第三者に送信しようとしており、この投稿に誘導されました。

SQL Fiddleで私のユースケースに合わせて微調整しようとした後、ストアドプロシージャはタイムアウトし続けます。
そのため、ローカルで 2 回 (PhpMyAdmin 経由で) 試してみました。
ストアド プロシージャを呼び出した後、ブラウザで PMA をリロードしようとすると、永遠に「応答待ち」スピナーが表示されます (10 分または 20 分以上)。

私のSPコードに何か問題があると思います???

CREATE TABLE foo
    (`id` int, `name` varchar(100), `parentId` int, `path` varchar(100))
//

INSERT INTO foo (`id`, `name`, `parentId`, `path`)
VALUES (1, 'discrete', 0, NULL),
       (2, 'res', 1, NULL),
       (3, 'smt', 2, NULL),
       (4, 'cap', 1, NULL),
       (5, 'ind', 1, NULL),
       (6, 'smt', 4, NULL),
       (7, 'tant', 6, NULL),
       (8, 'cer', 6, NULL)
//

CREATE PROCEDURE updatePath()
BEGIN
DECLARE cnt, n int;
    SELECT COUNT(*) INTO n FROM foo WHERE parentId = 0;
    UPDATE foo a, foo b SET a.path = b.name WHERE b.parentId IS NULL AND a.parentId = b.id;
    SELECT count(*) INTO cnt FROM foo WHERE path IS NULL;
    while cnt > n do
        UPDATE foo a, foo b SET a.path = concat(b.path, '|', b.id) WHERE b.path IS NOT NULL AND a.parentId = b.id;
        SELECT count(*) INTO  cnt FROM foo WHERE path IS NULL;
    end while;
END//

EDIT
期待される結果:

VALUES (1, 'discrete', 0, '1'),
       (2, 'res', 1, '1|2'),
       (3, 'smt', 2, '1|2|3'),
       (4, 'cap', 1, '1|4'),
       (5, 'ind', 1, '1|5'),
       (6, 'smt', 4, '1|4|6'),
       (7, 'tant', 6, '1|4|6|7'),
       (8, 'cer', 6, '1|4|6|8');
4

2 に答える 2

1

ぐっすり眠った後、@Drew のリードを取り、一度に 1 台の PC を実行しました。
動作しました。ここに私はそれを残しています:

CREATE TABLE foo
    (`id` int, `name` varchar(100), `parentId` int, `path` varchar(100))
//

INSERT INTO foo
    (`id`, `name`, `parentId`, `path`)
VALUES
    (1, 'dscr', 0, NULL),
    (2, 'res', 1, NULL),
    (3, 'smt', 2, NULL),
    (4, 'cap', 1, NULL),
    (5, 'ind', 1, NULL),
    (6, 'chp', 4, NULL),
    (7, 'tant', 6, NULL),
    (8, 'cer', 6, NULL)
//

CREATE PROCEDURE updatePath()
BEGIN
DECLARE cnt, n int;

    SELECT COUNT(*) INTO n FROM foo WHERE parentId = 0; -- n is now 1
    SELECT COUNT(*) INTO cnt FROM foo WHERE path IS NULL; -- cnt is now 8

    UPDATE foo child, foo parent        -- each child now has its parent and own ID's in the path
      SET child.path = CONCAT(parent.id, '|', child.id)
      WHERE parent.parentId = 0
      AND child.parentId = parent.id;

    WHILE cnt > n DO
        UPDATE foo child, foo parent    -- concat parent's path and own ID into each empty child's path
          SET child.path = concat( parent.path,'|',child.id ) 
          WHERE parent.path IS NOT NULL 
          AND child.parentId = parent.id;

        SELECT COUNT(*) INTO  cnt  -- decrement cnt
          FROM foo 
          WHERE path IS NULL;

    END WHILE;

    UPDATE foo  -- set path for any top-level categories
      SET path = id
      WHERE path IS NULL;

END//

call updatePath()//

気軽に批評してください。
これが他の誰かに役立つことを願っています。

于 2016-06-03T20:46:46.290 に答える
0

自己参照結合を実行して階層を作成しようとしていますか?

foo a から a.name、parentName = b.name を選択し、foo b を外部結合します ( a.id = b.parentId )

于 2016-06-02T23:46:27.763 に答える