Intereting Posts
Добавить поле для загрузки в регистровую форму с помощью CodeIgniter Определите следующий номер в запросе базы данных с циклом while в php MySQL Запросить два разных условия для разных счетчиков в 1 запросе PHP XML DOM Исключить исключение «DOMException» с сообщением «Ошибка неправильного документа» Laravel Eloquent ORM returnig stdClass вместо реальной модели Скрытие заголовка PHP X-Powered-By Применение css в php-таблице Отправьте форму на один сервер, обработайте ее, а затем опубликуйте результаты в другом домене полностью застрял на RegEx, который работает на тестовой песочнице, но не работает вживую PHP DOM XML – создание нескольких атрибутов пространства имен? Бит-маска в PHP для настроек? str_get_html не загружает действительную строку html Тайм-аут по умолчанию в PHP Расширенная фильтрация коллекции связанных лиц в Symfony PHP – объединить два массива (одинаковой длины) в один ассоциативный?

Получить сумму из дерева узлов

Я изучаю php. У меня есть эта структура

company 1 - $10| all $50 -company 1.1 - $10| all $20 --company 1.1.1 - 10$| all $10 -company 1.2 - $20| all $20 

каждая компания может иметь несколько дочерних компаний и может иметь только одного родителя. У каждой компании есть деньги. Все компании имеют Allmoney – собственные деньги + деньги всех его дочерних компаний.

В MySQL эта структура подобна этой

 id|parent_id|name|money|allmoney 1| 0| company 1| 10|### 2| 1| company 1.1|10 |### 3| 2| company 1.1.1|10 |### 4| 1| company 1.2|10 |### 

так, как я рассчитываю allmoney для каждой компании в php? Я сейчас, что нужно использовать рекурсию, но я стараюсь, и ничего не может случиться. SELECT, UPDATE и другая команда mysql – я знаю, пожалуйста, помогите мне с php. Я пишу что-то вроде этого:

 function updatemoney($id) { $data = CS50::query("SELECT ...", $id); $allmoney = 0; if(count($data) > 0) { foreach($data as $row) { $allmoney += $row["cash"]; //somewhere this, maybe need ubdate my db $allmoney += updatemoney($row["id"]); } } else return 0; } 

большое спасибо

LTREE

Вы почти на правильном пути. Вы почти наткнулись на «LTREE» систему хранения иерархических данных в базе данных. Вам просто нужно сделать небольшую модификацию. это все.

Ваша таблица может выглядеть так:

 CREATE TABLE Table1 (`id` int, `parent_id` int, `name` varchar(13), `path` char(10), `money` int) ; 

И ваши данные могут выглядеть так.

 (1, 0, 'company 1', '1', 10), (2, 1, 'child 1', '1.1', 10), (3, 2, 'child 2', '1.1.1', 10), (4, 1, 'child 3', '1.2', 10,), (4, 1, 'company 2', '2', 10), (4, 1, 'child 2.1', '2.1', 10) 

Столбец пути помогает определить, какая компания является дочерней компанией другой компании. Обратите внимание, что вам действительно не нужна колонка allmoney . Это динамически генерируется.

И как вы находите все деньги, принадлежащие первой компании?

 select sum(money) from Table1 where path >= '1' and path < '2' 

Обратите внимание, что в структуре, которую мы создали, child1 является родительским для child2. Итак, как мы можем найти allmoney для child1?

 select sum(money) from Table1 where path >= '1.1' and path < '1.2' 

Существует только один запрос и нет рекурсии.

MPTT

Еще один популярный подход для выборки иерархических данных – это использование измененного предварительного трейрования дерева заказов. На протяжении многих лет на сайте Sitepoint была отличная статья, в которой объясняется, как это делается с образцом кода лота.

Мое решение

 function updatemoney($id) { $child = mysql_query("SELECT * FROM `company` WHERE `parent_id` = ?", $id); if(empty($child)) { mysql_query("UPDATE `company` SET `allcash`=`cash` WHERE `id`=?", $id); } else { for($i = 0; $i< count($child); $i++) { updatemoney($child[$i]["id"]); } $childmoney = mysql_query("SELECT sum(`allcash`) AS `total` FROM `company` WHERE `parent_id` = ?", $id); $parentmoney = mysql_query("SELECT `cash` FROM `company` WHERE `id` = ?", $id); $sum = $childmoney[0]["total"] + $parentmoney[0]["cash"]; mysql_query("UPDATE `company` SET `allcash`=? WHERE `id`=?", $sum, $id); }