MySQL « Выборка дерева из MYSQL

Задался интересным вопросом, а реально ли из MYSQL выбрать дерево данных используя примитивный запрос, вот к примеру код на который MySQL в прицепе не ругается, остаётся только спросить реально сделать функцию json(cursor, field1, field2, fieldY) которая бы могла работать с курсором и вытянуть данные о пользователе, аватарках пользователя и фотографиях пользователя одним единственным запросом?

/** * GeSHi (C) 2004 - 2007 Nigel McNie, 2007 - 2008 Benny Baumann * (http://qbnz.com/highlighter/ and http://geshi.org/) */ .sql.geshi_code {font-family:monospace;} .sql.geshi_code .imp {font-weight: bold; color: red;} .sql.geshi_code .kw1 {color: #993333; font-weight: bold;} .sql.geshi_code .co1 {color: #808080; font-style: italic;} .sql.geshi_code .co2 {color: #808080; font-style: italic;} .sql.geshi_code .coMULTI {color: #808080; font-style: italic;} .sql.geshi_code .es0 {color: #000099; font-weight: bold;} .sql.geshi_code .br0 {color: #66cc66;} .sql.geshi_code .sy0 {color: #66cc66;} .sql.geshi_code .st0 {color: #ff0000;} .sql.geshi_code .nu0 {color: #cc66cc;} .sql.geshi_code span.xtra { display:block; }
SELECT u.*, json(avatars) AS avatars, json(p, "path", "comment") AS photos
FROM users u, avatars a, photos p
WHERE
 u.usrid = 544 AND
 a.usrid = u.usrid AND
 a.active = 1 AND
 p.usrid = u.usrid LIMIT 1



ps : Очень люблю идеи и примеры.

1 ответов


вот вариант с использованием рекурсии и временной таблицы


CREATE PROCEDURE `rpids`(IN `npid` INT, IN `nlev` INT, IN `ntmp` TINYINT)
BEGIN
    DECLARE done INT DEFAULT 0;
    DECLARE a,b,d INT;
    DECLARE c VARCHAR(16);
    DECLARE cur1 CURSOR FOR SELECT `id`,`pid`,`name` FROM `pids` WHERE `pid` = npid;
    DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done = 1;
    SET MAX_SP_RECURSION_DEPTH = 10;
    IF ntmp = 1 THEN
        DROP TEMPORARY TABLE IF EXISTS tmp;
        CREATE TEMPORARY TABLE IF NOT EXISTS `tmp`(
            `id` int(10) UNSIGNED NOT NULL,
            `pid` int(10) UNSIGNED NOT NULL,
            `lev` int(10) UNSIGNED NOT NULL,
            `coupids` int(10) UNSIGNED NOT NULL,
            `name` varchar(16) NOT NULL);
    END IF;
    OPEN cur1;
    REPEAT
        FETCH cur1 INTO a, b, c;
        IF NOT done THEN
            SELECT COUNT(id) INTO d FROM `pids` WHERE `pid` = a;
            INSERT INTO `tmp` VALUES (a, b, nlev, d, c);
            CALL rpids(a, nlev + 1, 0);
        END IF;
    UNTIL done END REPEAT;
    CLOSE cur1;
    IF ntmp = 1 THEN
        SELECT *, concat(space(lev * 3), name) FROM `tmp`;
    END IF;
END
 
Вызов:

CALL rpids(0, 0, 1);