Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / MySQL [игнор отключен] [закрыт для гостей] / Обновление счётчиков / 2 сообщений из 2, страница 1 из 1
13.09.2013, 00:30:00
    #38395362
RomanFov
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Обновление счётчиков
Всем доброго времени суток и с уже наступившим праздником)).
Столкнулся с задачей, незнаю даже с какого края к ней подступится.
Имеетются таблицы:
`items`:
idnamegroup_id1Имя112762Имя212763Имя325544Имя413255Имя5165.........
`group_id` - идентификатор группы в которой находится итем (`groups`.`id`)

`groups`:
idnameparent_group_idcount_children_items............165 Название группы1 25 1501277Название группы11 165781325Название группы1111277152554Название группы1121277 52555Название группы2 242532556Название группы21 255599............
`parent_group_id` - идентификатор группы родителя
`count_children_items` - количество итемов в папке и дочерних папках

`houses`:
iditems_idcount.........11 0.0021 0.0031 3.0042 5.5053 0.0064 1.207510.00.........
`items_id` - идентификатор итемa (`items`.`id`)

После добавления записей в таблицу `items`, вполне естественно, не обновляются счетчики (`count_children_items`) в таблице `items`.

Нужно составить запрос чтоб обновить счётчики, да не простой.
Строки из таблицы `items` y которых сумма `houses`.`count` из соответствующих строк равна нулю не должны суммироваться к `groups`.`count_children_items`.

Но и это ещё не всё, в дереве групп есть одна ветвь для которой нужно суммировать все итемы (независимо от значений `houses`.`count`)
В данном случае этоа ветвь `groups`.`id` = 2555 и 2556.

Хотелось бы узнать мнение более опытных людей, как это пограмотней реализовать.
...
Рейтинг: 0 / 0
13.09.2013, 05:53:15
    #38395409
tanglir
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Обновление счётчиков
одним запросом - никак
даже и двумя
вот, посмотрите на это, оформите в хранимку, погоняйте (на тестовой безе!)
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
declare privgroup unsigned -- корень вышеуказанной ветви "`groups`.`id` = 2555 и 2556."
/*ну или не корень, а та нода, от которой и ниже все итемы должны учитываться несмотря ни на что*/
declare lcount unsigned;
declare curlevel unsigned;

-- таблица нод: уровень,ид,ид родителя, признак привгруппы, кол-во
create temporary table tmp_levels (level int,id int, parentid int, priv_group tinyint, res_count int);
-- мускль не умеет апдейтить таблицу, если в апдейте есть подзапрос к ней же
-- это, может, и правильно, но нам понадобится как раз такой (по сути) запрос :)
-- поэтому создаём доп. табличку
create temporary table tl2 (parentid int, sum_res_count int); 
-- таблица итемов (с суммами)
create temporary table tmp_items (gid int,cnt int);

-- считаем суммы для итемгрупп (чтобы видеть нули):
insert into tmp_items
select i.group_id
 ,ifnull(sum(h.`count`),0) as c 
from items i
left join houses h on h.items_id=i.id
group by 1;
-- alter table tmp_items add index (gid);

-- теперь наполняем таблицу нод:
set curlevel:=0;
repeat
if curlevel=0 /*на 0 уровне только "корни"*/
 insert into tmp_levels 
 select curlevel,id,parent_group_id
  ,case when id=privgroup then 1 else 0 end /*признак "особой ветки"*/
  ,0
 from groups 
 where parent_group_id is null; 
else /*а глубже - берём идшники с предыдущего этапа и ищем их потомков*/
 insert into tmp_levels 
 select curlevel,id,parent_group_id
  ,case when id=privgroup or t1.priv_group=1 then 1 else 0 end
  ,0
 from groups 
 join tmp_levels tl on groups.parent_group_id=tl.id 
 where tl.level=curlevel-1;
end if;
-- смотрим, нашлись ли потомки на текущем уровне
select count(*) into lcount from tmp_levels where level=curlevel; 
set curlevel:=curlevel+1;
until lcount=0 -- or curlevel>=500;
-- если потомков не нашлось, то выходим

-- alter table tmp_levels add index (id);
-- alter table tl2 add index (id);
 
-- дальше идём по дереву "в обратную сторону" - от листьев к корням
repeat
-- рассчитываем текущий уровень
update tmp_levels tl
set res_count=
 (select count(*) 
  from tmp_items 
  where gid=tl.id and (cnt<>0 or tl.priv_group=1)
 ) /*суммы айтемов по нодам текущего уровня с учётом нулей и привгруппы*/
 +
 (select ifnull(sum_res_count,0)
  from tl2 where parentid=tl.id
 ) /*и суммы по нижележащим связанным нодам (там всё уже учтено на предыдущем этапе)*/
where level=curlevel;
-- теперь надо записать рассчитанные суммы для обработки на следующем этапе...
insert into tl2 select parentid,sum(res_count)
from tmp_level
where level=curlevel
group by 1;
-- поднимаемся на уровень выше
set curlevel:=curlevel-1; 
until curlevel<0; -- и так пока не дойдём до самого верха


-- теперь в таблице tmp_levels лежат подсчитанные количества
-- уж как проапдейтить исходную таблицу, надеюсь, догадаетсь

...
Рейтинг: 0 / 0
Форумы / MySQL [игнор отключен] [закрыт для гостей] / Обновление счётчиков / 2 сообщений из 2, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]