sql复杂树行

时间:2009-08-14 16:47:51

标签: mysql sql treeview

我有一个查询功能。它与整数id工作正常,但如果id是varchar(ID:Xewi3adc),那么它不起作用。好吧,我不知道如何让它工作,我一直在做很多修改,但我不能让它工作。

DROP FUNCTION IF EXISTS album_tree_connect;

DELIMITER $$

CREATE FUNCTION album_tree_connect(value varchar(32)) RETURNS INT
NOT DETERMINISTIC
READS SQL DATA
BEGIN
    DECLARE _id varchar(32);
    DECLARE _parent varchar(32);
    DECLARE _next INT;
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET @id = NULL;

    SET _parent = @id;
    SET _id = -1;

    IF @id IS NULL THEN
        RETURN NULL;
    END IF;

    LOOP
        SELECT  MIN(album_id)
        INTO    @id
        FROM    album
        WHERE   sub_album_of_album_id = _parent
            AND album_id > _id;
        IF @id IS NOT NULL OR _parent = @start_with THEN
            SET @level = @level + 1;
            RETURN @id;
        END IF;
        SET @level := @level - 1;
        SELECT  album_id, sub_album_of_album_id
        INTO    _id, _parent
        FROM    album
        WHERE   album_id = _parent;
    END LOOP;   
END
$$

DELIMITER ;


## select statement to pull the tree menu

SELECT   CONCAT(REPEAT('    ', level - 1), CAST(hi.album_id AS CHAR)) AS treeitem, sub_album_of_album_id, name, user_id, level
FROM    (
        SELECT  album_tree_connect(album_id) AS id, @level AS level
        FROM    (
                SELECT  @start_with := 0,
                        @id := @start_with,
                        @level := 0
                ) vars, album
        WHERE   @id IS NOT NULL
        ) ho
JOIN    album hi
ON      hi.album_id = ho.id
where user_id = 2

2 个答案:

答案 0 :(得分:3)

您的函数返回类型声明为INT,因此返回值将被强制转换为该类型。如果要返回的值(album_id字段)不是整数,则可能会损坏。 http://dev.mysql.com/doc/refman/5.0/en/create-procedure.html

答案 1 :(得分:1)

首先,将您的函数声明修改为GApple建议:

CREATE FUNCTION album_tree_connect(value varchar(32)) RETURNS VARCHAR(32)

其次,应将初始_id初始化为emtpy字符串,而不是-1

SET _id = '';

第三,您的@start_with也应该用字符串(用作父节点标识符的字符串)初始化:

SELECT   CONCAT(REPEAT('    ', level - 1),
         CAST(hi.album_id AS CHAR)) AS treeitem, sub_album_of_album_id, name, user_id, level
FROM    (
        SELECT  album_tree_connect(album_id) AS id, @level AS level
        FROM    (
                SELECT  @start_with := '0',

                        --- The '0' above should be a string.

                        @id := @start_with,
                        @level := 0
                ) vars, album
        WHERE   @id IS NOT NULL
        ) ho
JOIN    album hi
ON      hi.album_id = ho.id

请注意,上述查询中user_id上的过滤器很可能无法正常工作。

您需要将函数包装到子查询中:

SELECT  *
FROM    (
        SELECT   CONCAT(REPEAT('    ', level - 1),
                 CAST(hi.album_id AS CHAR)) AS treeitem, sub_album_of_album_id, name, user_id, level
        FROM    (
                SELECT  album_tree_connect(album_id) AS id, @level AS level
                FROM    (
                        SELECT  @start_with := '0',

                                --- The '0' above should be a string.

                                @id := @start_with,
                                @level := 0
                        ) vars, album
                WHERE   @id IS NOT NULL
                ) ho
        JOIN    album hi
        ON      hi.album_id = ho.id
        ) q
WHERE   user_id = 2

或修改分层函数以考虑过滤器。