Рекурсия рефералов на PHP и MySQL

Прошу момощи просить массив на php с рефералами вида

Array
(
    [1] => Array
        (
            [0] => 6
            [1] => 5
        ),
    [2] => Array
        (
            [0] => 8
            [1] => 7
        ),
    [3] => Array
        (
            [0] => 9
        ),
    [4] => Array
        (
            [0] => 10
        )
)

Будет 4 уровня (уровень 1 ключ массива)

Код

//Рекурсия
function get_refs($user, $level, $data = array()) {
    //Получим список реферов пользоваптеля
    $row = db_get_array("SELECT `id` FROM `users` WHERE `ref` = '$user' ORDER BY `id` DESC");
    //Если есть результат
    if ($row) {
        //Цикл
        foreach ($row as $ref) {
            //Добавим в массив
            $data[$level][] = $ref["id"];
            //Вызовем функцию
            $data[$level] = get_refs($ref["id"], $level, $data);
        }
    }
    $level++;
    return $data;
}

Таблица MySQL 5.1

CREATE TABLE IF NOT EXISTS `users` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `ref` int(11) NOT NULL DEFAULT '0',
  `login` varchar(100) NOT NULL,
  PRIMARY KEY (`id`) USING BTREE,
  UNIQUE KEY `login` (`login`)
) ENGINE=MyISAM AUTO_INCREMENT=11 DEFAULT CHARSET=utf8;

INSERT INTO `users` (`id`, `ref`, `login`) VALUES
    (3, 2, 'user'),
    (5, 3, 'user2'),
    (6, 3, 'user3'),
    (7, 6, 'user4'),
    (8, 6, 'user5'),
    (9, 7, 'user6'),
    (10, 9, 'user7');

Ответы (1 шт):

Автор решения: Akina

MySQL 5.1

Какая однако седая древность... для неё только разве что

SELECT 1 AS level, id
FROM users t1
WHERE NOT EXISTS ( SELECT NULL
                   FROM users t0
                   WHERE t0.id = t1.ref )
UNION ALL
SELECT 2, t2.id
FROM users t1
JOIN users t2 ON t1.id = t2.ref
WHERE NOT EXISTS ( SELECT NULL
                   FROM users t0
                   WHERE t0.id = t1.ref )
UNION ALL
SELECT 3, t3.id
FROM users t1
JOIN users t2 ON t1.id = t2.ref
JOIN users t3 ON t2.id = t3.ref
WHERE NOT EXISTS ( SELECT NULL
                   FROM users t0
                   WHERE t0.id = t1.ref )
UNION ALL
SELECT 4, t4.id
FROM users t1
JOIN users t2 ON t1.id = t2.ref
JOIN users t3 ON t2.id = t3.ref
JOIN users t4 ON t3.id = t4.ref
WHERE NOT EXISTS ( SELECT NULL
                   FROM users t0
                   WHERE t0.id = t1.ref )
ORDER BY level, id;

fiddle

Можно получать данные отдельными запросами, можно все 4 уровня сразу объединяющим запросом, а можно и сразу все кусты финальным запросом.

На PHP осталось получить что-то из указанного (отдельные уровни в 4 запроса, всё кучей и т.п.) и конвертировать полученный набор записей в требуемую структуру (не думаю. что это зело сложно).

→ Ссылка