2016-08-18 5 views
1

I`ve получили следующую таблицу в MySQLMysql дерево траверсы и сосчитать

id|top_id|amount 
1 NULL  2 
2 NULL  8 
3 NULL  4 
4  3  7 
5  2  8 
6  2  4 
7  5  5 
8  7  1 
9  6  6 
10  8  6 

Для первых 3 идентификаторов мне нужно суммировать все количество его наследников, чтобы получить следующее:

id | amount 
1   8 
2   32 
3   11 

Я предполагаю, что должны быть соединения, но, к сожалению, я не могу получить рабочий запрос mysql. Может кто-нибудь мне помочь?

UPD: В PHP У меня есть следующий запрос:

$tops = $mysqli->query('SELECT * FROM table WHERE top_id IS NULL') 

, который, очевидно, возвращает меня только 3 верхних идентификаторов и их простые суммы (2, 8 и 4 соответственно). Вместо 2, 8 и 4 мне нужно получить 12, 28 и 11, и это проблема ((

+0

Если у вас есть установленный предел, как «глубоко» ваше дерево может идти, вы не можете сделать это с помощью простого MySQL. MySQL не поддерживает рекурсивные запросы. вы можете подделать для определенной глубины с помощью самосоединений, но произвольная глубина в принципе невозможна без использования внешних циклов в клиентском коде. –

+0

Итак, варианты включают: объединение таблицы в себя так часто, как это может потребоваться, построение sproc для обработки рекурсия, используя некоторый внешний код t o обрабатывать рекурсию; изменение модели данных (к вложенному набору, скажем) – Strawberry

+0

Мне это нужно для PHP-кода. Может быть, есть идеи использовать рекурсивный запрос там? – Jack

ответ

0

Это самое грубое решение ... Несомненно, кто-то предоставит некоторые подсказки для более масштабируемого решения в ближайшее время (возможно, с использованием PHP) ...

SELECT a.id 
    , COALESCE(a.amount,0) 
    + COALESCE(b.amount,0) 
    + COALESCE(c.amount,0) 
    + COALESCE(d.amount,0) 
    + COALESCE(e.amount,0) 
    + COALESCE(f.amount,0) total 
    FROM my_table a 
    LEFT 
    JOIN my_table b 
    ON b.top_id = a.id 
    LEFT 
    JOIN my_table c 
    ON c.top_id = b.id 
    LEFT 
    JOIN my_table d 
    ON d.top_id = c.id 
    LEFT 
    JOIN my_table e 
    ON e.top_id = d.id 
    LEFT 
    JOIN my_table f 
    ON f.top_id = e.id 
WHERE a.top_id IS NULL; 
+0

Большое вам спасибо, я проверю это – Jack

+0

Я узнал, что это решение не работает, если у нас есть несколько потомков одного родителя. Я изменил первую таблицу. Он учитывается отдельно для пользователя с ID 2 и не складывает все (( – Jack

+0

А, но есть обходное решение для этого – Strawberry

Смежные вопросы